diff --git a/DEPS b/DEPS
index ecaa419..a6cc14d 100644
--- a/DEPS
+++ b/DEPS
@@ -133,11 +133,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': '2f9297dff115615218ddba3e1805103de35b9862',
+  'skia_revision': '68eb8c276355687ccd3f56f2279232f7fe1a9ebc',
   # 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': '30b5ab61e732f0606c5eeef973bd817a9ad38a51',
+  'v8_revision': '07e4ce2cfbcb74b9662f379ef8747a25d4c927a6',
   # 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.
@@ -145,11 +145,11 @@
   # 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': '565441b1078b6eabf6f3d1785c5c5de9fd5271a9',
+  'angle_revision': '3928567b8c5f843d6bba870d0bde05de72cd79e0',
   # 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': '58edd47c2c9de72ad580d5cecdb1416250f4a1ab',
+  'swiftshader_revision': '82ae7cbccf2008aec4b34e916a99356c17bb19dd',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -200,7 +200,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': '5a34ef7bdaf7e88601764c191f6ea7002b99a805',
+  'catapult_revision': '23edc497039adbbf7453107cd9ee68133b45b98d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -256,7 +256,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': 'c8b09744c6a15f3586c26351376bf5c6f656e89f',
+  'spv_tools_revision': '6d04da22c6c7362ac6dd55b291a22cb21303ffe6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -272,11 +272,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': '00f6b1af41cab2dfa75a0c2759a3602307f2e9fd',
+  'dawn_revision': '94274b63fb2230c0e18261b3bb985e1b6aff56ee',
   # 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': '82d12d19ed7a93a1fe491c25e6e78ae289d45b9c',
+  'quiche_revision': '7bf7c3c358eb954e463bde14ea27444f4bd8ea05',
   # 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.
@@ -831,7 +831,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'fe1dbe120c9905324026fa503ac1690dc96e16e2',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0647cd502cea650b29b33c0082dcc5c836eb2c39',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1184,7 +1184,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '3cefa2e3358b3fc2b75d97ee435025633bb8fc45',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '7a3221f8bedc119e4c756ca54871d96aad132c12',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1355,7 +1355,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'a0421d3d0cd7fac9e178900cbd59f5a2006615a2',
+    Var('webrtc_git') + '/src.git' + '@' + '4fb12b0caec9faa57cfbceb0f86b0e10c32a0cc2',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1396,7 +1396,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@263da2a5734e4fdb0fa9704e02d7c496f349cb93',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3e41647c15c8cc57d6c15fd9d4555c430ad13a5c',
     'condition': 'checkout_src_internal',
   },
 
@@ -2408,7 +2408,7 @@
     'name': 'clang_tot',
     'pattern': '.',
     'condition': 'llvm_force_head_revision',
-    'action': ['python', 'src/tools/clang/scripts/update.py',
+    'action': ['python', 'src/tools/clang/scripts/build.py',
                '--llvm-force-head-revision',
                '--with-android={checkout_android}'],
   },
diff --git a/android_webview/browser/aw_permission_manager.cc b/android_webview/browser/aw_permission_manager.cc
index 5ad3272..455db38 100644
--- a/android_webview/browser/aw_permission_manager.cc
+++ b/android_webview/browser/aw_permission_manager.cc
@@ -30,10 +30,10 @@
 namespace {
 
 void PermissionRequestResponseCallbackWrapper(
-    const base::Callback<void(PermissionStatus)>& callback,
+    base::OnceCallback<void(PermissionStatus)> callback,
     const std::vector<PermissionStatus>& vector) {
   DCHECK_EQ(vector.size(), 1ul);
-  callback.Run(vector[0]);
+  std::move(callback).Run(vector.at(0));
 }
 
 }  // namespace
@@ -233,11 +233,12 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(PermissionStatus)>& callback) {
+    base::OnceCallback<void(PermissionStatus)> callback) {
   return RequestPermissions(
       std::vector<PermissionType>(1, permission), render_frame_host,
       requesting_origin, user_gesture,
-      base::Bind(&PermissionRequestResponseCallbackWrapper, callback));
+      base::BindOnce(&PermissionRequestResponseCallbackWrapper,
+                     std::move(callback)));
 }
 
 int AwPermissionManager::RequestPermissions(
@@ -245,10 +246,9 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(const std::vector<PermissionStatus>&)>&
-        callback) {
+    base::OnceCallback<void(const std::vector<PermissionStatus>&)> callback) {
   if (permissions.empty()) {
-    callback.Run(std::vector<PermissionStatus>());
+    std::move(callback).Run(std::vector<PermissionStatus>());
     return content::PermissionController::kNoPendingOperation;
   }
 
@@ -257,7 +257,7 @@
   auto pending_request = std::make_unique<PendingRequest>(
       permissions, requesting_origin, embedding_origin,
       GetRenderProcessID(render_frame_host),
-      GetRenderFrameID(render_frame_host), callback);
+      GetRenderFrameID(render_frame_host), std::move(callback));
   std::vector<bool> should_delegate_requests =
       std::vector<bool>(permissions.size(), true);
   for (size_t i = 0; i < permissions.size(); ++i) {
@@ -279,7 +279,7 @@
   // Keep copy of pointer for performing further operations after ownership is
   // transferred to pending_requests_
   PendingRequest* pending_request_raw = pending_request.get();
-  int request_id = pending_requests_.Add(std::move(pending_request));
+  const int request_id = pending_requests_.Add(std::move(pending_request));
 
   AwBrowserPermissionRequestDelegate* delegate =
       GetDelegate(pending_request_raw->render_process_id,
@@ -362,8 +362,10 @@
   // without invoking the callback.
   if (pending_request_raw->IsCompleted()) {
     std::vector<PermissionStatus> results = pending_request_raw->results;
+    RequestPermissionsCallback completed_callback =
+        std::move(pending_request_raw->callback);
     pending_requests_.Remove(request_id);
-    callback.Run(results);
+    std::move(completed_callback).Run(results);
     return content::PermissionController::kNoPendingOperation;
   }
 
@@ -454,7 +456,7 @@
     PermissionType permission,
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
-    const base::Callback<void(PermissionStatus)>& callback) {
+    base::RepeatingCallback<void(PermissionStatus)> callback) {
   return content::PermissionController::kNoPendingOperation;
 }
 
diff --git a/android_webview/browser/aw_permission_manager.h b/android_webview/browser/aw_permission_manager.h
index d6ab44a..0fcfd662 100644
--- a/android_webview/browser/aw_permission_manager.h
+++ b/android_webview/browser/aw_permission_manager.h
@@ -24,20 +24,19 @@
   ~AwPermissionManager() override;
 
   // PermissionControllerDelegate implementation.
-  int RequestPermission(
-      content::PermissionType permission,
-      content::RenderFrameHost* render_frame_host,
-      const GURL& requesting_origin,
-      bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
-      override;
+  int RequestPermission(content::PermissionType permission,
+                        content::RenderFrameHost* render_frame_host,
+                        const GURL& requesting_origin,
+                        bool user_gesture,
+                        base::OnceCallback<void(blink::mojom::PermissionStatus)>
+                            callback) override;
   int RequestPermissions(
       const std::vector<content::PermissionType>& permissions,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<
-          void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
+      base::OnceCallback<
+          void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
       override;
   void ResetPermission(content::PermissionType permission,
                        const GURL& requesting_origin,
@@ -54,7 +53,7 @@
       content::PermissionType permission,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
+      base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
       override;
   void UnsubscribePermissionStatusChange(int subscription_id) override;
 
diff --git a/android_webview/browser/aw_settings.cc b/android_webview/browser/aw_settings.cc
index 6d820dd..d3232088 100644
--- a/android_webview/browser/aw_settings.cc
+++ b/android_webview/browser/aw_settings.cc
@@ -239,7 +239,6 @@
 
   if (!renderer_prefs_initialized_) {
     content::UpdateFontRendererPreferencesFromSystemSettings(prefs);
-    content::UpdateFocusRingPreferencesFromSystemSettings(prefs);
     renderer_prefs_initialized_ = true;
     update_prefs = true;
   }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
index adfa29c3..19443ce 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
@@ -14,6 +14,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.CalledByNativeUnchecked;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.PostTask;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.net.NetError;
@@ -335,8 +336,12 @@
                                 response.action(), response.reporting(), requestId));
         // clang-format on
 
-        mClient.getCallbackHelper().postOnSafeBrowsingHit(
-                request, AwSafeBrowsingConversionHelper.convertThreatType(threatType), callback);
+        int webViewThreatType = AwSafeBrowsingConversionHelper.convertThreatType(threatType);
+        mClient.getCallbackHelper().postOnSafeBrowsingHit(request, webViewThreatType, callback);
+
+        // Record UMA on threat type
+        RecordHistogram.recordEnumeratedHistogram("Android.WebView.onSafeBrowsingHit.ThreatType",
+                webViewThreatType, AwSafeBrowsingConversionHelper.SAFE_BROWSING_THREAT_BOUNDARY);
     }
 
     @CalledByNative
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java
index 2f881e4..4d9db88 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java
@@ -14,6 +14,10 @@
  * constants in WebViewClient.
  */
 public final class AwSafeBrowsingConversionHelper {
+    // These values are used for UMA. Entries should not be renumbered and
+    // numeric values should never be reused. The BOUNDARY constant should be
+    // updated when adding new constants.
+
     /** The resource was blocked for an unknown reason. */
     public static final int SAFE_BROWSING_THREAT_UNKNOWN =
             WebViewClient.SAFE_BROWSING_THREAT_UNKNOWN;
@@ -30,6 +34,8 @@
     // TODO(ntfschr): replace this with the named constant when we roll the Q SDK
     // (http://crbug.com/887186).
     public static final int SAFE_BROWSING_THREAT_BILLING = 4;
+    /** Boundary for Safe Browsing Threat values, used for UMA recording. */
+    public static final int SAFE_BROWSING_THREAT_BOUNDARY = 5;
 
     /**
      * Converts the threat type value from SafeBrowsing code to the WebViewClient constant.
diff --git a/android_webview/tools/webview_log_verbosifier/AndroidManifest.xml b/android_webview/tools/webview_log_verbosifier/AndroidManifest.xml
index ed9188b..63de091 100644
--- a/android_webview/tools/webview_log_verbosifier/AndroidManifest.xml
+++ b/android_webview/tools/webview_log_verbosifier/AndroidManifest.xml
@@ -11,5 +11,8 @@
 
     <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
 
-    <application android:label="WebView Log Verbosifier" />
+    <application
+        android:label="WebView Log Verbosifier"
+        android:icon="@mipmap/ic_launcher"
+        android:roundIcon="@mipmap/ic_launcher_round" />
 </manifest>
diff --git a/android_webview/tools/webview_log_verbosifier/BUILD.gn b/android_webview/tools/webview_log_verbosifier/BUILD.gn
index b746e44..772c5b0 100644
--- a/android_webview/tools/webview_log_verbosifier/BUILD.gn
+++ b/android_webview/tools/webview_log_verbosifier/BUILD.gn
@@ -7,4 +7,12 @@
 android_apk("webview_log_verbosifier_apk") {
   apk_name = "WebViewLogVerbosifier"
   android_manifest = "AndroidManifest.xml"
+  deps = [
+    ":webview_log_verbosifier_resources",
+  ]
+}
+
+android_resources("webview_log_verbosifier_resources") {
+  resource_dirs = [ "res" ]
+  custom_package = "org.chromium.webview_log_verbosifier"
 }
diff --git a/android_webview/tools/webview_log_verbosifier/res/drawable-v24/ic_launcher_foreground.xml b/android_webview/tools/webview_log_verbosifier/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..30d691a
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,214 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="79.92008"
+    android:viewportHeight="79.92008">
+  <group android:translateX="15.96004"
+      android:translateY="15.96004">
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M5.5,2v27h9.8L24,14h22V2H5.5z"
+          android:fillColor="#455A64"/>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M15.6,28.9l-10,-17.1l-0.1,0.2l9.9,17L15.6,28.9z"
+          android:fillColor="#263238"
+          android:fillAlpha="0.15"/>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M2,46h20.9l9.7,-9.7V29H15.3L2,6.1V46z"
+          android:fillColor="#37474F"/>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M32.5,29.3l-0.2,-0.1L22.7,46h0.3L32.5,29.3L32.5,29.3z"
+          android:fillColor="#263238"
+          android:fillAlpha="0.15"/>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <group>
+        <clip-path android:pathData="M2,46l20.9,0l9.8,-9.7l0,-7.3l-17.4,0l-13.3,-22.9z M 0,0"/>
+        <path
+            android:pathData="M24,14l8.7,15l-9.7,17H46V14H24z"
+            android:fillColor="#607D8B"/>
+        <path
+            android:pathData="M24,14l8.7,15l-9.7,17H46V14H24z">
+          <aapt:attr name="android:fillColor">
+            <gradient 
+                android:startY="12.4524"
+                android:startX="30.46385"
+                android:endY="28.533875"
+                android:endX="34.1361"
+                android:type="linear">
+              <item android:offset="0" android:color="#4C263238"/>
+              <item android:offset="0.66" android:color="#00263238"/>
+            </gradient>
+          </aapt:attr>
+        </path>
+      </group>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M24,14l8.7,15l-9.7,17H46V14H24z"
+          android:fillColor="#607D8B"/>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <group>
+        <clip-path android:pathData="M24,14l8.7,15l-9.8,17l23.1,0l0,-32z M 0,0"/>
+        <path
+            android:pathData="M5.5,2v27h9.8L24,14h22V2H5.5z"
+            android:fillColor="#455A64"/>
+        <path
+            android:pathData="M5.5,2v27h9.8L24,14h22V2H5.5z">
+          <aapt:attr name="android:fillColor">
+            <gradient 
+                android:startY="18.75635"
+                android:startX="7.3341"
+                android:endY="11.0896"
+                android:endX="20.4591"
+                android:type="linear">
+              <item android:offset="0" android:color="#99263238"/>
+              <item android:offset="0.66" android:color="#00263238"/>
+            </gradient>
+          </aapt:attr>
+        </path>
+      </group>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M24,14v5.2L43.6,14H24z">
+        <aapt:attr name="android:fillColor">
+          <gradient 
+              android:gradientRadius="21.0195"
+              android:centerX="23.04395"
+              android:centerY="13.98825"
+              android:type="radial">
+            <item android:offset="0" android:color="#33263238"/>
+            <item android:offset="1" android:color="#00263238"/>
+          </gradient>
+        </aapt:attr>
+      </path>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <group>
+        <clip-path android:pathData="M5.5,2l0,10.1l9.8,16.9l8.7,-15l22,0l0,-12z M 0,0"/>
+        <path
+            android:pathData="M2,46h20.9l9.7,-9.7V29H15.3L2,6.1V46z"
+            android:fillColor="#37474F"/>
+        <path
+            android:pathData="M2,46h20.9l9.7,-9.7V29H15.3L2,6.1V46z">
+          <aapt:attr name="android:fillColor">
+            <gradient 
+                android:startY="41.1244"
+                android:startX="27.7183"
+                android:endY="32.582874"
+                android:endX="13.134775"
+                android:type="linear">
+              <item android:offset="0" android:color="#66263238"/>
+              <item android:offset="0.33" android:color="#00263238"/>
+            </gradient>
+          </aapt:attr>
+        </path>
+      </group>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M5.5,12.1l14.3,14.3L15.3,29L5.5,12.1z">
+        <aapt:attr name="android:fillColor">
+          <gradient 
+              android:gradientRadius="19.511"
+              android:centerX="5.4687"
+              android:centerY="12.13125"
+              android:type="radial">
+            <item android:offset="0" android:color="#33263238"/>
+            <item android:offset="0.112" android:color="#2D2A3034"/>
+            <item android:offset="0.595" android:color="#14392927"/>
+            <item android:offset="1" android:color="#003E2723"/>
+          </gradient>
+        </aapt:attr>
+      </path>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M23,46l5.2,-19.5l4.5,2.6L23,46z">
+        <aapt:attr name="android:fillColor">
+          <gradient 
+              android:gradientRadius="21.9675"
+              android:centerX="23.96095"
+              android:centerY="24.035774"
+              android:type="radial">
+            <item android:offset="0" android:color="#33263238"/>
+            <item android:offset="1" android:color="#00263238"/>
+          </gradient>
+        </aapt:attr>
+      </path>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M24,24m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
+          android:fillColor="#F1F1F1"/>
+      <path
+          android:pathData="M24,24m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"
+          android:fillColor="#4285F4"/>
+    </group>
+    <group>
+      <clip-path android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z M 0,0"/>
+      <path
+          android:pathData="M24,13.8c-5.5,0 -10,4.5 -10,10V24c0,-5.5 4.5,-10 10,-10h22v-0.2H24z"
+          android:fillColor="#263238"
+          android:fillAlpha="0.2"/>
+      <path
+          android:pathData="M32.6,29c-1.7,3 -5,5 -8.6,5c-3.7,0 -6.9,-2 -8.7,-5h0L2,6.1v0.2l13.3,22.9h0c1.7,3 5,5 8.7,5c3.7,0 6.9,-2 8.6,-5h0L32.6,29L32.6,29z"
+          android:fillColor="#FFFFFF"
+          android:fillAlpha="0.1"/>
+      <path
+          android:pathData="M24.2,14c0,0 -0.1,0 -0.1,0c5.5,0.1 9.9,4.5 9.9,10s-4.4,9.9 -9.9,10c0,0 0.1,0 0.1,0c5.5,0 10,-4.5 10,-10S29.8,14 24.2,14z"
+          android:strokeAlpha="0.1"
+          android:fillColor="#263238"
+          android:fillAlpha="0.1"/>
+      <path
+          android:pathData="M32.7,29.3c0.8,-1.5 1.3,-3.2 1.3,-5c0,-1.1 -0.2,-2.1 -0.5,-3c0.2,0.9 0.4,1.8 0.4,2.7c0,1.8 -0.5,3.5 -1.3,5l0,0l-9.7,17h0.3L32.7,29.3C32.8,29.3 32.7,29.3 32.7,29.3z"
+          android:fillColor="#FFFFFF"
+          android:fillAlpha="0.1"/>
+    </group>
+    <path
+        android:pathData="M3.6,30.3c-0.3,0.3 -0.5,0.8 -0.5,1.2c0,-0.4 0.2,-0.7 0.5,-1l3,-2.7c0.6,-0.6 1,-1.4 1,-2.2v-0.2c0,0.8 -0.3,1.6 -1,2.2L3.6,30.3zM44.4,30.3l-3,-2.7c-0.6,-0.6 -1,-1.4 -1,-2.2v0.2c0,0.8 0.3,1.6 1,2.2l3,2.7c0.3,0.3 0.4,0.6 0.5,1C44.9,31.1 44.7,30.6 44.4,30.3zM41.4,10.4l3.2,5.6c0.1,0.2 0.2,0.4 0.2,0.6c0,-0.3 0,-0.6 -0.2,-0.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.2,0.3 -0.2,0.6 -0.2,0.9c0,-0.2 0.1,-0.4 0.2,-0.6l3.2,-5.6c0.4,-0.6 1.1,-0.9 1.8,-0.7l3.8,1.2c0.8,0.3 1.7,0.2 2.4,-0.3L17,9.4c0.7,-0.4 1.3,-1.1 1.4,-2l0.8,-4c0.1,-0.7 0.7,-1.2 1.5,-1.2h6.5c0.7,0 1.3,0.5 1.5,1.2l0.8,3.9c0.2,0.8 0.7,1.6 1.4,2l2.4,1.4c0.7,0.4 1.6,0.5 2.4,0.3l3.8,-1.2C40.3,9.5 41.1,9.8 41.4,10.4z"
+        android:fillColor="#FFFFFF"
+        android:fillAlpha="0.2"/>
+    <path
+        android:pathData="M6.6,20.4c0.6,0.6 1,1.4 1,2.2v-0.2c0,-0.8 -0.3,-1.6 -1,-2.2l-3,-2.7c-0.3,-0.3 -0.5,-0.6 -0.5,-1c0,0.5 0.1,0.9 0.5,1.2C3.6,17.7 6.6,20.4 6.6,20.4zM44.9,16.4c0,0.4 -0.2,0.7 -0.5,1l-3,2.7c-0.6,0.6 -1,1.4 -1,2.2v0.2c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7C44.7,17.4 44.9,16.9 44.9,16.4zM39.7,38.2L35.8,37c-0.8,-0.3 -1.7,-0.2 -2.4,0.3L31,38.7c-0.7,0.4 -1.3,1.1 -1.4,2l-0.8,4c-0.1,0.7 -0.7,1.2 -1.5,1.2h-6.5c-0.7,0 -1.3,-0.5 -1.5,-1.2l-0.8,-4c-0.2,-0.8 -0.7,-1.5 -1.4,-2l-2.4,-1.4c-0.7,-0.4 -1.6,-0.5 -2.4,-0.3l-3.8,1.2c-0.7,0.2 -1.4,-0.1 -1.8,-0.7l-3.2,-5.6c-0.1,-0.2 -0.2,-0.4 -0.2,-0.6c0,0.3 0,0.6 0.2,0.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.2,-0.3 0.2,-0.6 0.2,-0.9c0,0.2 -0.1,0.4 -0.2,0.6l-3.2,5.6C41.1,38.2 40.3,38.5 39.7,38.2z"
+        android:fillColor="#263238"
+        android:fillAlpha="0.2"/>
+    <path
+        android:pathData="M41.4,27.6c-0.6,-0.6 -1,-1.4 -1,-2.2v-2.8c0,-0.8 0.3,-1.6 1,-2.2l3,-2.7c0.5,-0.5 0.7,-1.2 0.3,-1.9l-3.2,-5.6c-0.4,-0.6 -1.1,-0.9 -1.8,-0.7l-3.8,1.2c-0.8,0.3 -1.7,0.2 -2.4,-0.3L31,9.1c-0.7,-0.4 -1.3,-1.1 -1.4,-2l-0.8,-4C28.6,2.5 28,2 27.2,2h-6.5c-0.7,0 -1.3,0.5 -1.5,1.2l-0.8,3.9c-0.2,0.8 -0.7,1.6 -1.4,2l-2.4,1.4c-0.7,0.4 -1.6,0.5 -2.4,0.3L8.3,9.5c-0.7,-0.2 -1.4,0.1 -1.8,0.7l-3.2,5.6c-0.4,0.6 -0.2,1.4 0.3,1.9l3,2.7c0.6,0.6 1,1.4 1,2.2v2.8c0,0.8 -0.3,1.6 -1,2.2l-3,2.7c-0.5,0.5 -0.7,1.2 -0.3,1.9l3.2,5.6c0.4,0.6 1.1,0.9 1.8,0.7l3.8,-1.2c0.8,-0.3 1.7,-0.2 2.4,0.3l2.4,1.4c0.7,0.4 1.3,1.1 1.4,2l0.8,4c0.1,0.7 0.7,1.2 1.5,1.2h6.5c0.7,0 1.3,-0.5 1.5,-1.2l0.8,-4c0.2,-0.8 0.7,-1.5 1.4,-2l2.4,-1.4c0.7,-0.4 1.6,-0.5 2.4,-0.3l3.8,1.2c0.7,0.2 1.4,-0.1 1.8,-0.7l3.2,-5.6c0.4,-0.6 0.2,-1.4 -0.3,-1.9L41.4,27.6L41.4,27.6z">
+      <aapt:attr name="android:fillColor">
+        <gradient 
+            android:gradientRadius="45.19325"
+            android:centerX="8.078175"
+            android:centerY="7.97375"
+            android:type="radial">
+          <item android:offset="0" android:color="#19FFFFFF"/>
+          <item android:offset="1" android:color="#00FFFFFF"/>
+        </gradient>
+      </aapt:attr>
+    </path>
+    <path
+        android:pathData="M30.6,25h-5.8l1,-1l-1,-1h5.8V25zM27.1,25.9h-3.2l-1.9,1.9h5.2V25.9zM30.6,20.2h-8.7l1.9,1.9h6.8V20.2zM22.7,22.6l-2.5,-2.5h-2.7l3.8,3.8l-3.8,3.8h2.7l2.5,-2.5L24,24L22.7,22.6z"
+        android:fillColor="#FFFFFF"/>
+  </group>
+</vector>
diff --git a/android_webview/tools/webview_log_verbosifier/res/drawable/ic_launcher_background.xml b/android_webview/tools/webview_log_verbosifier/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..0d025f9b
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillColor="#008577"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+</vector>
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-anydpi-v26/ic_launcher.xml b/android_webview/tools/webview_log_verbosifier/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android_webview/tools/webview_log_verbosifier/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-hdpi/ic_launcher.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..0ac9e02
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-hdpi/ic_launcher_round.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..e10576c
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-mdpi/ic_launcher.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..5adb687
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-mdpi/ic_launcher_round.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4711afc4
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-xhdpi/ic_launcher.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6339a87e
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-xhdpi/ic_launcher_round.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8fbe577e
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-xxhdpi/ic_launcher.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2b6889a
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-xxhdpi/ic_launcher_round.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4376859b
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-xxxhdpi/ic_launcher.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..e9cdfa9
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/mipmap-xxxhdpi/ic_launcher_round.png b/android_webview/tools/webview_log_verbosifier/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..f5daf2c
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/android_webview/tools/webview_log_verbosifier/res/values/ic_launcher_background.xml b/android_webview/tools/webview_log_verbosifier/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..c5d5899
--- /dev/null
+++ b/android_webview/tools/webview_log_verbosifier/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="ic_launcher_background">#FFFFFF</color>
+</resources>
\ No newline at end of file
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index c348bab..c43e36f 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -667,8 +667,6 @@
     "system/cast/unified_cast_detailed_view_controller.cc",
     "system/cast/unified_cast_detailed_view_controller.h",
     "system/enterprise/enterprise_domain_observer.h",
-    "system/flag_warning/flag_warning_tray.cc",
-    "system/flag_warning/flag_warning_tray.h",
     "system/ime/ime_feature_pod_controller.cc",
     "system/ime/ime_feature_pod_controller.h",
     "system/ime/ime_observer.h",
@@ -1769,7 +1767,6 @@
     "system/bluetooth/bluetooth_power_controller_unittest.cc",
     "system/bluetooth/tray_bluetooth_helper_legacy_unittest.cc",
     "system/caps_lock_notification_controller_unittest.cc",
-    "system/flag_warning/flag_warning_tray_unittest.cc",
     "system/ime/ime_feature_pod_controller_unittest.cc",
     "system/ime_menu/ime_menu_tray_unittest.cc",
     "system/locale/locale_feature_pod_controller_unittest.cc",
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index a047afe..2864016 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -482,8 +482,8 @@
       <message name="IDS_ASH_AUTOCLICK_OPTION_DOUBLE_CLICK" desc="The tooltip text for a menu option for the automatic clicks menu that results in the next automatic click being a double-click.">
         Double click
       </message>
-      <message name="IDS_ASH_AUTOCLICK_OPTION_DRAG_AND_DROP" desc="The tooltip text for a menu option for the automatic clicks menu that results in the next automatic click being a drag-and-drop.">
-        Drag and drop
+      <message name="IDS_ASH_AUTOCLICK_OPTION_DRAG_AND_DROP" desc="The tooltip text for a menu option for the automatic clicks menu that results in the next automatic click being a click and drag action.">
+        Click and drag
       </message>
       <message name="IDS_ASH_AUTOCLICK_OPTION_NO_ACTION" desc="The tooltip text for a menu option for the automatic clicks menu that results in pausing the automatic clicks feature without disabling it.">
         No action (pause)
diff --git a/ash/resources/vector_icons/autoclick_drag.icon b/ash/resources/vector_icons/autoclick_drag.icon
index 3f3be42..7636fb9 100644
--- a/ash/resources/vector_icons/autoclick_drag.icon
+++ b/ash/resources/vector_icons/autoclick_drag.icon
@@ -3,36 +3,30 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 20,
-R_MOVE_TO, 9, 11,
-R_H_LINE_TO, -4.71f,
-R_LINE_TO, 1.95f, 1.87f,
-R_LINE_TO, -1.15f, 1.13f,
-R_LINE_TO, -4.09f, -4,
-R_LINE_TO, 4.09f, -4,
-R_LINE_TO, 1.15f, 1.13f,
-R_LINE_TO, -1.87f, 1.87f,
-R_H_LINE_TO, 4.63f,
-R_V_LINE_TO, -4.71f,
-R_LINE_TO, -1.87f, 1.95f,
-R_LINE_TO, -1.13f, -1.15f,
-R_LINE_TO, 4, -4.09f,
-R_LINE_TO, 4, 4.09f,
-R_LINE_TO, -1.13f, 1.15f,
-R_LINE_TO, -1.87f, -1.87f,
-R_V_LINE_TO, 4.63f,
-R_H_LINE_TO, 4.71f,
-R_LINE_TO, -1.95f, -1.87f,
-R_LINE_TO, 1.15f, -1.13f,
-R_LINE_TO, 4.09f, 4,
-R_LINE_TO, -4.09f, 4,
-R_LINE_TO, -1.15f, -1.13f,
-R_LINE_TO, 1.87f, -1.87f,
-R_H_LINE_TO, -4.63f,
-R_V_LINE_TO, 4.71f,
-R_LINE_TO, 1.87f, -1.95f,
-R_LINE_TO, 1.13f, 1.15f,
-R_LINE_TO, -4, 4.09f,
-R_LINE_TO, -4, -4.09f,
-R_LINE_TO, 1.13f, -1.15f,
-R_LINE_TO, 1.87f, 1.87f,
+MOVE_TO, 12, 14,
+CUBIC_TO, 10.9f, 14, 10, 13.1f, 10, 12,
+CUBIC_TO, 10, 10.9f, 10.9f, 10, 12, 10,
+CUBIC_TO, 13.1f, 10, 14, 10.9f, 14, 12,
+CUBIC_TO, 14, 13.1f, 13.1f, 14, 12, 14,
+CLOSE,
+MOVE_TO, 9.24f, 7.83f,
+CUBIC_TO, 10.03f, 7.31f, 10.98f, 7, 12, 7,
+CUBIC_TO, 14.76f, 7, 17, 9.24f, 17, 12,
+CUBIC_TO, 17, 14.76f, 14.76f, 17, 12, 17,
+CUBIC_TO, 9.24f, 17, 7, 14.76f, 7, 12,
+CUBIC_TO, 7, 10.98f, 7.31f, 10.03f, 7.83f, 9.24f,
+LINE_TO, 5, 6.41f,
+LINE_TO, 5, 9,
+LINE_TO, 3, 9,
+LINE_TO, 3, 3,
+LINE_TO, 9, 3,
+LINE_TO, 9, 5,
+LINE_TO, 6.41f, 5,
+LINE_TO, 9.24f, 7.83f,
+CLOSE,
+MOVE_TO, 12, 15,
+CUBIC_TO, 13.66f, 15, 15, 13.66f, 15, 12,
+CUBIC_TO, 15, 10.34f, 13.66f, 9, 12, 9,
+CUBIC_TO, 10.34f, 9, 9, 10.34f, 9, 12,
+CUBIC_TO, 9, 13.66f, 10.34f, 15, 12, 15,
 CLOSE
diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc
index 1cc9f1a..8df73b32 100644
--- a/ash/rotator/screen_rotation_animator.cc
+++ b/ash/rotator/screen_rotation_animator.cc
@@ -378,7 +378,8 @@
   DCHECK_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
   auto transfer_resource = viz::TransferableResource::MakeGL(
       result->GetTextureResult()->mailbox, GL_LINEAR, GL_TEXTURE_2D,
-      result->GetTextureResult()->sync_token);
+      result->GetTextureResult()->sync_token, result->size(),
+      false /* is_overlay_candidate */);
   std::unique_ptr<viz::SingleReleaseCallback> release_callback =
       result->TakeTextureOwnership();
   const gfx::Rect rect(
diff --git a/ash/system/flag_warning/flag_warning_tray.cc b/ash/system/flag_warning/flag_warning_tray.cc
deleted file mode 100644
index d22fa62..0000000
--- a/ash/system/flag_warning/flag_warning_tray.cc
+++ /dev/null
@@ -1,91 +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 "ash/system/flag_warning/flag_warning_tray.h"
-
-#include <memory>
-
-#include "ash/public/cpp/ash_typography.h"
-#include "ash/resources/vector_icons/vector_icons.h"
-#include "ash/shelf/shelf.h"
-#include "ash/shell.h"
-#include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_container.h"
-#include "base/logging.h"
-#include "base/strings/utf_string_conversions.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/base/ui_base_features.h"
-#include "ui/gfx/color_palette.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/paint_vector_icon.h"
-#include "ui/views/controls/button/md_text_button.h"
-#include "ui/views/layout/fill_layout.h"
-
-namespace ash {
-
-FlagWarningTray::FlagWarningTray(Shelf* shelf) : shelf_(shelf) {
-  DCHECK(shelf_);
-  SetLayoutManager(std::make_unique<views::FillLayout>());
-
-  container_ = new TrayContainer(shelf);
-  AddChildView(container_);
-
-  button_ = views::MdTextButton::Create(this, base::string16(),
-                                        CONTEXT_LAUNCHER_BUTTON);
-  button_->SetProminent(true);
-  button_->SetBgColorOverride(gfx::kGoogleYellow300);
-  button_->SetEnabledTextColors(SK_ColorBLACK);
-  button_->SetFocusBehavior(views::View::FocusBehavior::NEVER);
-  UpdateButton();
-  container_->AddChildView(button_);
-  SetVisible(true);
-}
-
-FlagWarningTray::~FlagWarningTray() = default;
-
-void FlagWarningTray::UpdateAfterShelfAlignmentChange() {
-  if (!container_)
-    return;
-
-  container_->UpdateAfterShelfAlignmentChange();
-  UpdateButton();
-}
-
-void FlagWarningTray::ButtonPressed(views::Button* sender,
-                                    const ui::Event& event) {
-  DCHECK_EQ(button_, sender);
-}
-
-void FlagWarningTray::GetAccessibleNodeData(ui::AXNodeData* node_data) {
-  View::GetAccessibleNodeData(node_data);
-  node_data->SetName(button_->GetText());
-}
-
-void FlagWarningTray::UpdateButton() {
-  if (!button_)
-    return;
-
-  // Only the horizontal shelf is wide enough for a text label. Use an icon for
-  // vertical shelf alignments.
-  if (!shelf_->IsHorizontalAlignment()) {
-    button_->SetText(base::string16());
-    button_->SetImage(
-        views::Button::STATE_NORMAL,
-        gfx::CreateVectorIcon(kSystemMenuInfoIcon, SK_ColorBLACK));
-    button_->SetMinSize(gfx::Size(kTrayItemSize, kTrayItemSize));
-    return;
-  }
-
-  if (::features::IsMultiProcessMash()) {
-    button_->SetText(base::ASCIIToUTF16("Mash"));
-    button_->SetTooltipText(base::ASCIIToUTF16("Running with feature Mash"));
-  } else {
-    NOTREACHED();
-  }
-  button_->SetImage(views::Button::STATE_NORMAL, gfx::ImageSkia());
-  button_->SetMinSize(gfx::Size(0, kTrayItemSize));
-}
-
-}  // namespace ash
diff --git a/ash/system/flag_warning/flag_warning_tray.h b/ash/system/flag_warning/flag_warning_tray.h
deleted file mode 100644
index 2c04fc82..0000000
--- a/ash/system/flag_warning/flag_warning_tray.h
+++ /dev/null
@@ -1,58 +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 ASH_SYSTEM_FLAG_WARNING_FLAG_WARNING_TRAY_H_
-#define ASH_SYSTEM_FLAG_WARNING_FLAG_WARNING_TRAY_H_
-
-#include <memory>
-
-#include "ash/ash_export.h"
-#include "base/macros.h"
-#include "ui/views/controls/button/button.h"
-#include "ui/views/view.h"
-
-namespace views {
-class MdTextButton;
-}
-
-namespace ash {
-class Shelf;
-class TrayContainer;
-
-// Adds an indicator to the status area if certain high-risk flags or features
-// are enabled, for example mash. Clicking the button opens about:flags so the
-// user can reset the flag. For consistency with other status area tray views,
-// this view is always created but only made visible when the flag is set.
-class ASH_EXPORT FlagWarningTray : public views::View,
-                                   public views::ButtonListener {
- public:
-  explicit FlagWarningTray(Shelf* shelf);
-  ~FlagWarningTray() override;
-
-  // Update the child view layout and appearance for horizontal or vertical
-  // shelf alignments.
-  void UpdateAfterShelfAlignmentChange();
-
-  // views::View:
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
-
-  // views::ButtonListener:
-  void ButtonPressed(views::Button* sender, const ui::Event& event) override;
-
- private:
-  // Update the button label and icon based on shelf state.
-  void UpdateButton();
-
-  const Shelf* const shelf_;
-
-  // Owned by views hierarchy.
-  TrayContainer* container_ = nullptr;
-  views::MdTextButton* button_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(FlagWarningTray);
-};
-
-}  // namespace ash
-
-#endif  // ASH_SYSTEM_FLAG_WARNING_FLAG_WARNING_TRAY_H_
diff --git a/ash/system/flag_warning/flag_warning_tray_unittest.cc b/ash/system/flag_warning/flag_warning_tray_unittest.cc
deleted file mode 100644
index 0c015221..0000000
--- a/ash/system/flag_warning/flag_warning_tray_unittest.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/system/flag_warning/flag_warning_tray.h"
-
-#include "ash/public/cpp/shell_window_ids.h"
-#include "ash/shell.h"
-#include "ash/system/status_area_widget.h"
-#include "ash/test/ash_test_base.h"
-#include "base/test/scoped_feature_list.h"
-#include "ui/base/ui_base_features.h"
-
-namespace ash {
-namespace {
-
-using FlagWarningTrayTest = AshTestBase;
-
-TEST_F(FlagWarningTrayTest, VisibleForMash) {
-  // Simulate enabling Mash.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      {::features::kMash} /* enabled */,
-      {::features::kSingleProcessMash} /* disabled */);
-
-  StatusAreaWidget widget(Shell::GetContainer(Shell::GetPrimaryRootWindow(),
-                                              kShellWindowId_StatusContainer),
-                          GetPrimaryShelf());
-  widget.Initialize();
-  FlagWarningTray* tray = widget.flag_warning_tray_for_testing();
-  ASSERT_TRUE(tray);
-  EXPECT_TRUE(tray->visible());
-}
-
-}  // namespace
-}  // namespace ash
diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc
index 37166c0..19923384 100644
--- a/ash/system/status_area_widget.cc
+++ b/ash/system/status_area_widget.cc
@@ -9,7 +9,6 @@
 #include "ash/shell.h"
 #include "ash/system/accessibility/dictation_button_tray.h"
 #include "ash/system/accessibility/select_to_speak_tray.h"
-#include "ash/system/flag_warning/flag_warning_tray.h"
 #include "ash/system/ime_menu/ime_menu_tray.h"
 #include "ash/system/overview/overview_button_tray.h"
 #include "ash/system/palette/palette_tray.h"
@@ -18,7 +17,6 @@
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/system/virtual_keyboard/virtual_keyboard_tray.h"
 #include "base/i18n/time_formatting.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/display/display.h"
 #include "ui/native_theme/native_theme_dark_aura.h"
 
@@ -44,11 +42,6 @@
 void StatusAreaWidget::Initialize() {
   // Create the child views, left to right.
 
-  if (::features::IsMultiProcessMash()) {
-    flag_warning_tray_ = std::make_unique<FlagWarningTray>(shelf_);
-    status_area_widget_delegate_->AddChildView(flag_warning_tray_.get());
-  }
-
   logout_button_tray_ = std::make_unique<LogoutButtonTray>(shelf_);
   status_area_widget_delegate_->AddChildView(logout_button_tray_.get());
 
@@ -103,7 +96,6 @@
   palette_tray_.reset();
   logout_button_tray_.reset();
   overview_button_tray_.reset();
-  flag_warning_tray_.reset();
 
   // All child tray views have been removed.
   DCHECK(GetContentsView()->children().empty());
@@ -119,8 +111,6 @@
     dictation_button_tray_->UpdateAfterShelfAlignmentChange();
   palette_tray_->UpdateAfterShelfAlignmentChange();
   overview_button_tray_->UpdateAfterShelfAlignmentChange();
-  if (flag_warning_tray_)
-    flag_warning_tray_->UpdateAfterShelfAlignmentChange();
   status_area_widget_delegate_->UpdateLayout();
 }
 
@@ -186,8 +176,6 @@
     dictation_button_tray_->SchedulePaint();
   palette_tray_->SchedulePaint();
   overview_button_tray_->SchedulePaint();
-  if (flag_warning_tray_)
-    flag_warning_tray_->SchedulePaint();
 }
 
 const ui::NativeTheme* StatusAreaWidget::GetNativeTheme() const {
diff --git a/ash/system/status_area_widget.h b/ash/system/status_area_widget.h
index 14dba40..8a2dfd2 100644
--- a/ash/system/status_area_widget.h
+++ b/ash/system/status_area_widget.h
@@ -17,7 +17,6 @@
 }
 
 namespace ash {
-class FlagWarningTray;
 class ImeMenuTray;
 class LogoutButtonTray;
 class OverviewButtonTray;
@@ -107,9 +106,6 @@
   VirtualKeyboardTray* virtual_keyboard_tray_for_testing() {
     return virtual_keyboard_tray_.get();
   }
-  FlagWarningTray* flag_warning_tray_for_testing() {
-    return flag_warning_tray_.get();
-  }
 
  private:
   friend class StatusAreaWidgetTestApi;
@@ -128,7 +124,6 @@
   std::unique_ptr<VirtualKeyboardTray> virtual_keyboard_tray_;
   std::unique_ptr<ImeMenuTray> ime_menu_tray_;
   std::unique_ptr<SelectToSpeakTray> select_to_speak_tray_;
-  std::unique_ptr<FlagWarningTray> flag_warning_tray_;
 
   LoginStatus login_status_ = LoginStatus::NOT_LOGGED_IN;
 
diff --git a/ash/wm/overview/caption_container_view.cc b/ash/wm/overview/caption_container_view.cc
index d0f8eae3..f92813bc 100644
--- a/ash/wm/overview/caption_container_view.cc
+++ b/ash/wm/overview/caption_container_view.cc
@@ -4,7 +4,9 @@
 
 #include "ash/wm/overview/caption_container_view.h"
 
+#include "ash/public/cpp/ash_features.h"
 #include "ash/wm/overview/rounded_rect_view.h"
+#include "ash/wm/window_preview_view.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/window.h"
 #include "ui/compositor/layer.h"
@@ -94,9 +96,11 @@
 
 CaptionContainerView::CaptionContainerView(EventDelegate* event_delegate,
                                            aura::Window* window,
+                                           bool show_preview,
                                            views::ImageButton* close_button)
     : Button(nullptr),
       event_delegate_(event_delegate),
+      window_(window),
       close_button_(close_button) {
   // This should not be focusable. It's also to avoid accessibility error when
   // |window->GetTitle()| is empty.
@@ -137,6 +141,14 @@
 
   if (close_button)
     AddChildWithLayer(header_view_, close_button);
+
+  // Call this last as it calls |Layout()| which relies on the some of the other
+  // elements existing.
+  SetShowPreview(show_preview);
+  if (show_preview) {
+    header_view_->layer()->SetOpacity(0.f);
+    current_header_visibility_ = HeaderVisibility::kInvisible;
+  }
 }
 
 CaptionContainerView::~CaptionContainerView() = default;
@@ -206,6 +218,42 @@
   SetAccessibleName(title);
 }
 
+void CaptionContainerView::SetShowPreview(bool show) {
+  if (show == !!preview_view_)
+    return;
+
+  if (!show) {
+    RemoveChildView(preview_view_);
+    preview_view_ = nullptr;
+    return;
+  }
+
+  preview_view_ = new wm::WindowPreviewView(window_, false);
+  AddChildWithLayer(this, preview_view_);
+  Layout();
+}
+
+void CaptionContainerView::UpdatePreviewRoundedCorners(bool show,
+                                                       float rounding) {
+  if (!preview_view_ || !ash::features::ShouldUseShaderRoundedCorner())
+    return;
+
+  const float scale = preview_view_->layer()->transform().Scale2d().x();
+  constexpr std::array<uint32_t, 4> kEmptyRadii = {0, 0, 0, 0};
+  const std::array<uint32_t, 4> kRadii = {rounding / scale, rounding / scale,
+                                          rounding / scale, rounding / scale};
+  preview_view_->layer()->SetRoundedCornerRadius(show ? kRadii : kEmptyRadii);
+  preview_view_->layer()->SetIsFastRoundedCorner(true);
+}
+
+void CaptionContainerView::UpdatePreviewView() {
+  if (!preview_view_)
+    return;
+
+  preview_view_->RecreatePreviews();
+  Layout();
+}
+
 void CaptionContainerView::Layout() {
   gfx::Rect bounds(GetLocalBounds());
   bounds.Inset(kMarginDp, kMarginDp);
@@ -216,6 +264,13 @@
     backdrop_view_->SetBoundsRect(backdrop_bounds);
   }
 
+  if (preview_view_) {
+    gfx::Rect preview_bounds = bounds;
+    preview_bounds.Inset(0, kHeaderPreferredHeightDp, 0, 0);
+    preview_bounds.ClampToCenteredSize(preview_view_->CalculatePreferredSize());
+    preview_view_->SetBoundsRect(preview_bounds);
+  }
+
   // Position the header at the top.
   const gfx::Rect header_bounds(kMarginDp, kMarginDp,
                                 GetLocalBounds().width() - kMarginDp,
diff --git a/ash/wm/overview/caption_container_view.h b/ash/wm/overview/caption_container_view.h
index da8ae04..7e8813128 100644
--- a/ash/wm/overview/caption_container_view.h
+++ b/ash/wm/overview/caption_container_view.h
@@ -21,9 +21,12 @@
 }  // namespace views
 
 namespace ash {
-
 class RoundedRectView;
 
+namespace wm {
+class WindowPreviewView;
+}  // namespace wm
+
 // CaptionContainerView covers the overview window and listens for events. It
 // also draws a header for overview mode which contains a icon, title and close
 // button.
@@ -57,8 +60,11 @@
     virtual ~EventDelegate() {}
   };
 
+  // If |show_preview| is true, this class will contain a child view which
+  // mirrors |window|.
   CaptionContainerView(EventDelegate* event_delegate,
                        aura::Window* window,
+                       bool show_preview,
                        views::ImageButton* close_button);
   ~CaptionContainerView() override;
 
@@ -82,9 +88,20 @@
   // Set the title of the view, and also updates the accessiblity name.
   void SetTitle(const base::string16& title);
 
+  // Creates or deletes |preview_view_| as needed.
+  void SetShowPreview(bool show);
+
+  void UpdatePreviewRoundedCorners(bool show, float rounding);
+
+  // Update |preview_view_| so that its content is up-to-date. Used by tab
+  // dragging.
+  void UpdatePreviewView();
+
+  // TODO(sammiequon): Move these to a test api.
   views::View* header_view() { return header_view_; }
   views::Label* title_label() { return title_label_; }
   RoundedRectView* backdrop_view() { return backdrop_view_; }
+  wm::WindowPreviewView* preview_view() { return preview_view_; }
 
  protected:
   // views::View:
@@ -100,6 +117,11 @@
   // The delegate which all the events get forwarded to.
   EventDelegate* event_delegate_;
 
+  // The window this class is meant to be a header for. This class also may
+  // optionally show a mirrored view of this window. This is needed when
+  // |window_| is minimized.
+  aura::Window* window_;
+
   // View which contains the icon, title and an optional close button.
   views::View* header_view_ = nullptr;
   views::Label* title_label_ = nullptr;
@@ -110,6 +132,9 @@
   // associated is not pillar or letter boxed.
   RoundedRectView* backdrop_view_ = nullptr;
 
+  // Optionally shows a preview of |window_|.
+  wm::WindowPreviewView* preview_view_ = nullptr;
+
   HeaderVisibility current_header_visibility_ = HeaderVisibility::kVisible;
 
   DISALLOW_COPY_AND_ASSIGN(CaptionContainerView);
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc
index 9f5df4b..220da116 100644
--- a/ash/wm/overview/overview_controller.cc
+++ b/ash/wm/overview/overview_controller.cc
@@ -433,7 +433,7 @@
 }
 
 bool OverviewController::IsSelecting() const {
-  return overview_session_ != nullptr;
+  return overview_session_ && !overview_session_->is_shutting_down();
 }
 
 bool OverviewController::IsCompletingShutdownAnimations() {
@@ -594,15 +594,28 @@
     OnStartingAnimationComplete(/*canceled=*/true);
   start_animations_.clear();
 
-  auto* overview_session = overview_session_.release();
+  overview_session_->set_is_shutting_down(true);
   // Do not show mask and show during overview shutdown.
-  overview_session->UpdateMaskAndShadow();
+  overview_session_->UpdateMaskAndShadow();
 
   for (auto& observer : observers_)
-    observer.OnOverviewModeEnding(overview_session);
-  overview_session->Shutdown();
+    observer.OnOverviewModeEnding(overview_session_.get());
+  overview_session_->Shutdown();
+
+#if DCHECK_IS_ON()
+  const auto enter_exit_type = overview_session_->enter_exit_overview_type();
+  if (enter_exit_type ==
+          OverviewSession::EnterExitOverviewType::kImmediateExit &&
+      !delayed_animations_.empty()) {
+    // Immediate exit type implies no delayed exit animations at all, if we get
+    // here then this is a bug.
+    NOTREACHED();
+  }
+#endif
+
   // Don't delete |overview_session_| yet since the stack is still using it.
-  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, overview_session);
+  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
+                                                  overview_session_.release());
   last_selection_time_ = base::Time::Now();
   for (auto& observer : observers_)
     observer.OnOverviewModeEnded();
@@ -612,6 +625,11 @@
 
 void OverviewController::AddExitAnimationObserver(
     std::unique_ptr<DelayedAnimationObserver> animation_observer) {
+  // No delayed animations should be created when overview mode is set to exit
+  // immediately.
+  DCHECK_NE(overview_session_->enter_exit_overview_type(),
+            OverviewSession::EnterExitOverviewType::kImmediateExit);
+
   animation_observer->SetOwner(this);
   delayed_animations_.push_back(std::move(animation_observer));
 }
diff --git a/ash/wm/overview/overview_controller.h b/ash/wm/overview/overview_controller.h
index 31a11a7..f3ad60eff 100644
--- a/ash/wm/overview/overview_controller.h
+++ b/ash/wm/overview/overview_controller.h
@@ -26,11 +26,6 @@
 class ASH_EXPORT OverviewController : public OverviewDelegate,
                                       public ::wm::ActivationChangeObserver {
  public:
-  enum class AnimationCompleteReason {
-    kCompleted,
-    kCanceled,
-  };
-
   OverviewController();
   ~OverviewController() override;
 
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index dc8d593..c19bf7bc 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -995,9 +995,12 @@
   if (Shell::Get()->kiosk_next_shell_controller()->IsEnabled())
     return false;
 
-  // Never animate when doing app dragging.
-  if (overview_session_->enter_exit_overview_type() ==
-      OverviewSession::EnterExitOverviewType::kWindowDragged) {
+  // Never animate when doing app dragging or when immediately exiting.
+  const auto enter_exit_type = overview_session_->enter_exit_overview_type();
+  if (enter_exit_type ==
+          OverviewSession::EnterExitOverviewType::kWindowDragged ||
+      enter_exit_type ==
+          OverviewSession::EnterExitOverviewType::kImmediateExit) {
     return false;
   }
 
@@ -1331,27 +1334,32 @@
   // If the selection widget is already active, fade it out in the selection
   // direction.
   if (selection_widget_ && (recreate_selection_widget || out_of_bounds)) {
-    // Animate the old selection widget and then destroy it.
-    views::Widget* old_selection = selection_widget_.get();
-    aura::Window* old_selection_window = old_selection->GetNativeWindow();
-    gfx::Vector2d fade_out_direction =
-        GetSlideVectorForFadeIn(direction, old_selection_window->bounds());
+    if (overview_session_->enter_exit_overview_type() ==
+        OverviewSession::EnterExitOverviewType::kImmediateExit) {
+      ImmediatelyCloseWidgetOnExit(std::move(selection_widget_));
+    } else {
+      // Animate the old selection widget and then destroy it.
+      views::Widget* old_selection = selection_widget_.get();
+      aura::Window* old_selection_window = old_selection->GetNativeWindow();
+      gfx::Vector2d fade_out_direction =
+          GetSlideVectorForFadeIn(direction, old_selection_window->bounds());
 
-    ScopedOverviewAnimationSettings settings(
-        OVERVIEW_ANIMATION_SELECTION_WINDOW, old_selection_window);
-    // CleanupAnimationObserver will delete itself (and the widget) when the
-    // motion animation is complete. Ownership over the observer is passed to
-    // the overview_session_->delegate() which has longer lifetime so that
-    // animations can continue even after the overview session is shut down.
-    std::unique_ptr<CleanupAnimationObserver> observer(
-        new CleanupAnimationObserver(std::move(selection_widget_)));
-    settings.AddObserver(observer.get());
-    overview_session_->delegate()->AddExitAnimationObserver(
-        std::move(observer));
-    old_selection->SetOpacity(0.f);
-    old_selection_window->SetBounds(old_selection_window->bounds() +
-                                    fade_out_direction);
-    old_selection->Hide();
+      ScopedOverviewAnimationSettings settings(
+          OVERVIEW_ANIMATION_SELECTION_WINDOW, old_selection_window);
+      // CleanupAnimationObserver will delete itself (and the widget) when the
+      // motion animation is complete. Ownership over the observer is passed to
+      // the overview_session_->delegate() which has longer lifetime so that
+      // animations can continue even after the overview session is shut down.
+      std::unique_ptr<CleanupAnimationObserver> observer(
+          new CleanupAnimationObserver(std::move(selection_widget_)));
+      settings.AddObserver(observer.get());
+      overview_session_->delegate()->AddExitAnimationObserver(
+          std::move(observer));
+      old_selection->SetOpacity(0.f);
+      old_selection_window->SetBounds(old_selection_window->bounds() +
+                                      fade_out_direction);
+      old_selection->Hide();
+    }
   }
   if (out_of_bounds)
     return;
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc
index df8fd38a..7fbe025 100644
--- a/ash/wm/overview/overview_item.cc
+++ b/ash/wm/overview/overview_item.cc
@@ -83,6 +83,60 @@
 constexpr SkColor kCloseButtonInkDropRippleHighlightColor =
     SkColorSetA(kCloseButtonColor, 0x14);
 
+OverviewAnimationType GetExitOverviewAnimationTypeForMinimizedWindow(
+    OverviewSession::EnterExitOverviewType type,
+    bool should_animate_when_exiting) {
+  // We should never get here when overview mode should exit immediately. The
+  // minimized window's |item_widget_| should be closed and destroyed
+  // immediately.
+  DCHECK_NE(type, OverviewSession::EnterExitOverviewType::kImmediateExit);
+
+  // EnterExitOverviewType can only be set to kWindowMinimized in talbet mode.
+  // Fade out the minimized window without animation if switch from tablet mode
+  // to clamshell mode.
+  if (type == OverviewSession::EnterExitOverviewType::kWindowsMinimized) {
+    return Shell::Get()
+                   ->tablet_mode_controller()
+                   ->IsTabletModeWindowManagerEnabled()
+               ? OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER
+               : OVERVIEW_ANIMATION_NONE;
+  }
+  return should_animate_when_exiting
+             ? OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT
+             : OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO;
+}
+
+// Applies |new_bounds| to |widget|, animating and observing the transform if
+// necessary.
+void SetWidgetBoundsAndMaybeAnimateTransform(
+    views::Widget* widget,
+    const gfx::Rect& new_bounds,
+    OverviewAnimationType animation_type,
+    ui::ImplicitAnimationObserver* observer) {
+  aura::Window* window = widget->GetNativeWindow();
+  gfx::RectF previous_bounds = gfx::RectF(window->GetBoundsInScreen());
+  window->SetBounds(new_bounds);
+  if (animation_type == OVERVIEW_ANIMATION_NONE)
+    return;
+
+  // For animations, compute the transform needed to place the widget at its
+  // new bounds back to the old bounds, and then apply the idenity
+  // transform. This so the bounds visually line up the concurrent transform
+  // animations. Also transform animations may be more performant.
+  // TODO(sammiequon): Move the transform calcuations to a utility function.
+  gfx::RectF current_bounds = gfx::RectF(window->GetBoundsInScreen());
+  gfx::Transform transform(previous_bounds.width() / current_bounds.width(),
+                           0.f, 0.f,
+                           previous_bounds.height() / current_bounds.height(),
+                           previous_bounds.x() - current_bounds.x(),
+                           previous_bounds.y() - current_bounds.y());
+  window->SetTransform(transform);
+  ScopedOverviewAnimationSettings settings(animation_type, window);
+  if (observer)
+    settings.AddObserver(observer);
+  window->SetTransform(gfx::Transform());
+}
+
 }  // namespace
 
 // The class to cache render surface to the specified window's layer.
@@ -203,16 +257,6 @@
   return transform_window_.window();
 }
 
-aura::Window* OverviewItem::GetWindowForStacking() {
-  // If the window is minimized, stack |widget_window| above the minimized
-  // window, otherwise the minimized window will cover |widget_window|. The
-  // minimized is created with the same parent as the original window, just
-  // like |item_widget_|, so there is no need to reparent.
-  return transform_window_.minimized_widget()
-             ? transform_window_.minimized_widget()->GetNativeWindow()
-             : GetWindow();
-}
-
 bool OverviewItem::Contains(const aura::Window* target) const {
   return transform_window_.Contains(target);
 }
@@ -231,8 +275,22 @@
 
   caption_container_view_->ResetEventDelegate();
   close_button_->ResetListener();
-  transform_window_.RestoreWindow(
-      reset_transform, overview_session_->enter_exit_overview_type());
+  transform_window_.RestoreWindow(reset_transform);
+
+  if (transform_window_.IsMinimized()) {
+    const auto enter_exit_type = overview_session_->enter_exit_overview_type();
+
+    if (enter_exit_type ==
+        OverviewSession::EnterExitOverviewType::kImmediateExit) {
+      ImmediatelyCloseWidgetOnExit(std::move(item_widget_));
+      return;
+    }
+
+    FadeOutWidgetAndMaybeSlideOnExit(
+        std::move(item_widget_),
+        GetExitOverviewAnimationTypeForMinimizedWindow(
+            enter_exit_type, should_animate_when_exiting_));
+  }
 }
 
 void OverviewItem::EnsureVisible() {
@@ -246,20 +304,20 @@
 void OverviewItem::PrepareForOverview() {
   transform_window_.PrepareForOverview();
   aura::Window* widget_window = item_widget_->GetNativeWindow();
-  widget_window->parent()->StackChildBelow(widget_window,
-                                           GetWindowForStacking());
+  widget_window->parent()->StackChildBelow(widget_window, GetWindow());
 }
 
 void OverviewItem::SlideWindowIn() {
-  // |transform_window_|'s |minimized_widget| is non null because this only gets
-  // called if we see the home launcher on enter (all windows are minimized).
-  DCHECK(transform_window_.minimized_widget());
-  // The |item_widget_| and mask and shadow will be shown when animation ends.
-  // Update the mask after starting the animation since starting the animation
-  // lets the controller know we are in starting animation.
-  FadeInWidgetAndMaybeSlideOnEnter(transform_window_.minimized_widget(),
+  // This only gets called if we see the home launcher on enter (all windows are
+  // minimized).
+  DCHECK(transform_window_.IsMinimized());
+
+  // The mask and shadow will be shown when animation ends. Update the mask
+  // after starting the animation since starting the animation lets the
+  // controller know we are in starting animation.
+  FadeInWidgetAndMaybeSlideOnEnter(item_widget_.get(),
                                    OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER,
-                                   /*slide=*/true);
+                                   /*slide=*/true, /*observe=*/true);
   UpdateMaskAndShadow();
 }
 
@@ -275,17 +333,21 @@
   std::vector<std::pair<ui::Layer*, int>> animation_layers_and_offsets = {
       {item_widget_->GetNativeWindow()->layer(), 0}};
 
-  // Transient children may already have a y translation relative to their base
-  // ancestor, so factor that in when computing their new y translation.
-  base::Optional<int> base_window_y_translation = base::nullopt;
-  for (auto* window : wm::GetTransientTreeIterator(GetWindowForStacking())) {
-    if (!base_window_y_translation.has_value()) {
-      base_window_y_translation = base::make_optional(
-          window->layer()->transform().To2dTranslation().y());
+  // For minimized windows we don't need to animate the original window or its
+  // transient ancestors since they are not visible.
+  if (!transform_window_.IsMinimized()) {
+    // Transient children may already have a y translation relative to their
+    // base ancestor, so factor that in when computing their new y translation.
+    base::Optional<int> base_window_y_translation = base::nullopt;
+    for (auto* window : wm::GetTransientTreeIterator(GetWindow())) {
+      if (!base_window_y_translation.has_value()) {
+        base_window_y_translation = base::make_optional(
+            window->layer()->transform().To2dTranslation().y());
+      }
+      const int offset = *base_window_y_translation -
+                         window->layer()->transform().To2dTranslation().y();
+      animation_layers_and_offsets.push_back({window->layer(), offset});
     }
-    const int offset = *base_window_y_translation -
-                       window->layer()->transform().To2dTranslation().y();
-    animation_layers_and_offsets.push_back({window->layer(), offset});
   }
 
   std::unique_ptr<ui::ScopedLayerAnimationSettings> settings_to_observe;
@@ -316,7 +378,7 @@
 }
 
 void OverviewItem::UpdateItemContentViewForMinimizedWindow() {
-  transform_window_.UpdateMinimizedWidget();
+  caption_container_view_->UpdatePreviewView();
 }
 
 float OverviewItem::GetItemScale(const gfx::Size& size) {
@@ -327,7 +389,7 @@
 }
 
 gfx::RectF OverviewItem::GetTargetBoundsInScreen() const {
-  return ::ash::GetTargetBoundsInScreen(transform_window_.GetOverviewWindow());
+  return ::ash::GetTargetBoundsInScreen(transform_window_.window());
 }
 
 gfx::RectF OverviewItem::GetTransformedBounds() const {
@@ -358,17 +420,42 @@
   gfx::RectF inset_bounds(target_bounds);
   inset_bounds.Inset(kWindowMargin, kWindowMargin);
 
-  // Do not animate if entering when the window is minimized, as it will be
-  // faded in. We still want to animate if the position is changed after
-  // entering.
-  if (wm::GetWindowState(GetWindow())->IsMinimized() && is_first_update)
-    new_animation_type = OVERVIEW_ANIMATION_NONE;
+  // If the window is minimized we can avoid applying transforms on the original
+  // window.
+  if (transform_window_.IsMinimized()) {
+    item_widget_->GetNativeWindow()->layer()->GetAnimator()->StopAnimating();
 
-  // SetItemBounds is called before UpdateHeaderLayout so the header can
-  // properly use the updated windows bounds.
-  SetItemBounds(inset_bounds, new_animation_type);
-  UpdateHeaderLayout(is_first_update ? OVERVIEW_ANIMATION_NONE
-                                     : new_animation_type);
+    gfx::Rect minimized_bounds = gfx::ToEnclosedRect(target_bounds);
+    minimized_bounds.Inset(-kWindowMargin, -kWindowMargin);
+    OverviewAnimationType minimized_animation_type =
+        is_first_update ? OVERVIEW_ANIMATION_NONE : new_animation_type;
+    SetWidgetBoundsAndMaybeAnimateTransform(
+        item_widget_.get(), minimized_bounds, minimized_animation_type,
+        minimized_animation_type ==
+                OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW
+            ? &transform_window_
+            : nullptr);
+
+    // On the first update show |item_widget_|. It's created on creation of
+    // |this|, and needs to be shown as soon as its bounds have been determined
+    // as it contains a mirror view of the window in its contents. The header
+    // will be faded in later to match non minimized windows.
+    if (is_first_update) {
+      if (should_animate_when_entering_) {
+        FadeInWidgetAndMaybeSlideOnEnter(
+            item_widget_.get(), OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
+            /*slide=*/false, /*observe=*/true);
+      } else {
+        item_widget_->GetNativeWindow()->layer()->SetOpacity(1.f);
+      }
+    }
+  } else {
+    // SetItemBounds is called before UpdateHeaderLayout so the header can
+    // properly use the updated windows bounds.
+    SetItemBounds(inset_bounds, new_animation_type);
+    UpdateHeaderLayout(is_first_update ? OVERVIEW_ANIMATION_NONE
+                                       : new_animation_type);
+  }
 
   // Shadow is normally set after an animation is finished. In the case of no
   // animations, manually set the shadow. Shadow relies on both the window
@@ -378,29 +465,13 @@
     UpdateMaskAndShadow();
 
   if (cannot_snap_widget_) {
-    gfx::RectF previous_bounds =
-        gfx::RectF(cannot_snap_widget_->GetNativeWindow()->GetBoundsInScreen());
     inset_bounds.Inset(
         gfx::Insets(static_cast<float>(kHeaderHeightDp), 0.f, 0.f, 0.f));
-    cannot_snap_widget_->SetBoundsCenteredIn(
-        gfx::ToEnclosingRect(inset_bounds));
-    if (new_animation_type != OVERVIEW_ANIMATION_NONE) {
-      // For animations, compute the transform needed to place the widget at its
-      // new bounds back to the old bounds, and then apply the idenity
-      // transform. This so the bounds visually line up with |item_widget_| and
-      // |window_|. This will not happen if we animate the bounds.
-      gfx::RectF current_bounds = gfx::RectF(
-          cannot_snap_widget_->GetNativeWindow()->GetBoundsInScreen());
-      gfx::Transform transform(
-          previous_bounds.width() / current_bounds.width(), 0.f, 0.f,
-          previous_bounds.height() / current_bounds.height(),
-          previous_bounds.x() - current_bounds.x(),
-          previous_bounds.y() - current_bounds.y());
-      cannot_snap_widget_->GetNativeWindow()->SetTransform(transform);
-      ScopedOverviewAnimationSettings settings(
-          new_animation_type, cannot_snap_widget_->GetNativeWindow());
-      cannot_snap_widget_->GetNativeWindow()->SetTransform(gfx::Transform());
-    }
+    SetWidgetBoundsAndMaybeAnimateTransform(
+        cannot_snap_widget_.get(),
+        cannot_snap_widget_->GetBoundsCenteredIn(
+            gfx::ToEnclosingRect(inset_bounds)),
+        new_animation_type, nullptr);
   }
 }
 
@@ -435,8 +506,9 @@
   AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM);
   if (cannot_snap_widget_)
     animate_window(cannot_snap_widget_->GetNativeWindow(), transform, false);
-  animate_window(item_widget_->GetNativeWindow(), transform, false);
-  animate_window(GetWindowForStacking(), transform, true);
+  if (!transform_window_.IsMinimized())
+    animate_window(GetWindow(), transform, false);
+  animate_window(item_widget_->GetNativeWindow(), transform, true);
 }
 
 void OverviewItem::CloseWindow() {
@@ -455,9 +527,15 @@
 }
 
 void OverviewItem::OnMinimizedStateChanged() {
-  transform_window_.UpdateMirrorWindowForMinimizedState();
-  if (window_surface_cache_observers_)
-    window_surface_cache_observers_->StartObserving(GetWindowForStacking());
+  const bool minimized = transform_window_.IsMinimized();
+  caption_container_view_->SetShowPreview(minimized);
+  if (minimized)
+    EnsureVisible();
+
+  if (window_surface_cache_observers_) {
+    window_surface_cache_observers_->StartObserving(
+        transform_window_.GetOverviewWindow());
+  }
 }
 
 void OverviewItem::UpdateCannotSnapWarningVisibility() {
@@ -516,7 +594,8 @@
   if (!features::ShouldUseShaderRoundedCorner()) {
     // Start caching render surface during overview window dragging.
     window_surface_cache_observers_ =
-        std::make_unique<WindowSurfaceCacheObserver>(GetWindowForStacking());
+        std::make_unique<WindowSurfaceCacheObserver>(
+            transform_window_.GetOverviewWindow());
   }
 }
 
@@ -586,7 +665,7 @@
 
   // First stack this item's window below the snapped window if split view mode
   // is active.
-  aura::Window* dragged_window = GetWindowForStacking();
+  aura::Window* dragged_window = GetWindow();
   aura::Window* dragged_widget_window = item_widget_->GetNativeWindow();
   aura::Window* parent_window = dragged_widget_window->parent();
   if (Shell::Get()->split_view_controller()->InSplitViewMode()) {
@@ -604,12 +683,13 @@
   const std::vector<std::unique_ptr<OverviewItem>>& overview_items =
       overview_grid_->window_list();
   aura::Window* stacking_target = nullptr;
-  for (size_t index = 0; index < overview_items.size(); index++) {
+  for (size_t index = 0; index < overview_items.size(); ++index) {
     if (index > 0) {
       aura::Window* window = overview_items[index - 1].get()->GetWindow();
       if (window->parent() == parent_window &&
           dragged_window->parent() == parent_window) {
-        stacking_target = window;
+        stacking_target =
+            overview_items[index - 1].get()->item_widget()->GetNativeWindow();
       }
     }
     if (overview_items[index].get() == this && stacking_target) {
@@ -669,22 +749,28 @@
     should_show = false;
   }
 
-  if (!should_show) {
-    transform_window_.UpdateMask(false);
-    SetShadowBounds(base::nullopt);
-    return;
+  transform_window_.UpdateMask(should_show);
+  SetShadowBounds(should_show ? base::make_optional(gfx::ToEnclosedRect(
+                                    transform_window_.GetTransformedBounds()))
+                              : base::nullopt);
+  if (transform_window_.IsMinimized()) {
+    caption_container_view_->UpdatePreviewRoundedCorners(
+        should_show, kOverviewWindowRoundingDp);
   }
-
-  transform_window_.UpdateMask(true);
-  SetShadowBounds(
-      gfx::ToEnclosedRect(transform_window_.GetTransformedBounds()));
 }
 
 void OverviewItem::OnStartingAnimationComplete() {
   DCHECK(item_widget_.get());
-  FadeInWidgetAndMaybeSlideOnEnter(
-      item_widget_.get(), OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
-      /*slide=*/false);
+  if (transform_window_.IsMinimized()) {
+    // Fade the title in if minimized. The rest of |item_widget_| should already
+    // be shown.
+    caption_container_view_->SetHeaderVisibility(
+        CaptionContainerView::HeaderVisibility::kVisible);
+  } else {
+    FadeInWidgetAndMaybeSlideOnEnter(
+        item_widget_.get(), OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
+        /*slide=*/false, /*observe=*/false);
+  }
   const bool show_backdrop =
       GetWindowDimensionsType() !=
       ScopedOverviewTransformWindow::GridWindowFillMode::kNormal;
@@ -704,12 +790,22 @@
 }
 
 OverviewAnimationType OverviewItem::GetExitOverviewAnimationType() {
+  if (overview_session_->enter_exit_overview_type() ==
+      OverviewSession::EnterExitOverviewType::kImmediateExit) {
+    return OVERVIEW_ANIMATION_NONE;
+  }
+
   return should_animate_when_exiting_
              ? OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT
              : OVERVIEW_ANIMATION_NONE;
 }
 
 OverviewAnimationType OverviewItem::GetExitTransformAnimationType() {
+  if (overview_session_->enter_exit_overview_type() ==
+      OverviewSession::EnterExitOverviewType::kImmediateExit) {
+    return OVERVIEW_ANIMATION_NONE;
+  }
+
   return should_animate_when_exiting_ ? OVERVIEW_ANIMATION_RESTORE_WINDOW
                                       : OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO;
 }
@@ -799,7 +895,7 @@
 
   if (reason == ui::PropertyChangeReason::NOT_FROM_ANIMATION) {
     if (window == GetWindow()) {
-      transform_window_.ResizeMinimizedWidgetIfNeeded();
+      caption_container_view_->UpdatePreviewView();
     } else {
       // Transient window is repositioned. The new position within the overview
       // item needs to be recomputed.
@@ -873,27 +969,15 @@
   // Do not set transform for drop target, set bounds instead.
   if (overview_grid_->IsDropTargetWindow(window)) {
     window->layer()->SetBounds(gfx::ToEnclosedRect(overview_item_bounds));
-    transform_window_.GetOverviewWindow()->SetTransform(gfx::Transform());
+    window->SetTransform(gfx::Transform());
     return;
   }
 
-  // Stop the current fade in animation if we shouldn't be animating.
-  if (wm::GetWindowState(window)->IsMinimized() &&
-      animation_type == OVERVIEW_ANIMATION_NONE) {
-    views::Widget* minimized_widget = transform_window_.minimized_widget();
-    if (minimized_widget) {
-      minimized_widget->GetNativeWindow()
-          ->layer()
-          ->GetAnimator()
-          ->StopAnimating();
-    }
-  }
-
   gfx::Transform transform = ScopedOverviewTransformWindow::GetTransformForRect(
       screen_rect, overview_item_bounds);
   ScopedOverviewTransformWindow::ScopedAnimationSettings animation_settings;
   transform_window_.BeginScopedAnimation(animation_type, &animation_settings);
-  SetTransform(transform_window_.GetOverviewWindow(), transform);
+  SetTransform(window, transform);
 }
 
 void OverviewItem::CreateWindowLabel() {
@@ -913,19 +997,18 @@
   item_widget_->set_focus_on_creation(false);
   item_widget_->Init(params);
   aura::Window* widget_window = item_widget_->GetNativeWindow();
-  widget_window->parent()->StackChildBelow(widget_window,
-                                           transform_window_.window());
+  widget_window->parent()->StackChildBelow(widget_window, GetWindow());
 
   shadow_ = std::make_unique<ui::Shadow>();
   shadow_->Init(kShadowElevation);
   item_widget_->GetLayer()->Add(shadow_->layer());
 
   close_button_ = new OverviewCloseButton(this);
-  caption_container_view_ =
-      new CaptionContainerView(this, GetWindow(), close_button_);
+  caption_container_view_ = new CaptionContainerView(
+      this, GetWindow(), transform_window_.IsMinimized(), close_button_);
   item_widget_->SetContentsView(caption_container_view_);
   item_widget_->Show();
-  item_widget_->SetOpacity(0);
+  item_widget_->SetOpacity(0.f);
   item_widget_->GetLayer()->SetMasksToBounds(false);
 }
 
@@ -993,7 +1076,7 @@
   transform_window_.CancelAnimationsListener();
 
   aura::Window* widget_window = item_widget_->GetNativeWindow();
-  aura::Window* window = GetWindowForStacking();
+  aura::Window* window = GetWindow();
   if (widget_window && widget_window->parent() == window->parent()) {
     // TODO(xdai): This might not work if there is an always on top window.
     // See crbug.com/733760.
diff --git a/ash/wm/overview/overview_item.h b/ash/wm/overview/overview_item.h
index 0eb89746e..6767aa8 100644
--- a/ash/wm/overview/overview_item.h
+++ b/ash/wm/overview/overview_item.h
@@ -43,11 +43,6 @@
 
   aura::Window* GetWindow();
 
-  // Returns the native window of the |transformed_window_|'s minimized widget
-  // if the original window is in minimized state, or the original window
-  // otherwise.
-  aura::Window* GetWindowForStacking();
-
   // Returns the root window on which this item is shown.
   aura::Window* root_window() { return root_window_; }
 
@@ -140,8 +135,6 @@
   // Increases the bounds of the dragged item.
   void ScaleUpSelectedItem(OverviewAnimationType animation_type);
 
-  const gfx::RectF& target_bounds() const { return target_bounds_; }
-
   // Shift the window item up and then animates it to its original spot. Used
   // to transition from the home launcher.
   void SlideWindowIn();
@@ -211,6 +204,10 @@
   // ui::ImplicitAnimationObserver:
   void OnImplicitAnimationsCompleted() override;
 
+  const gfx::RectF& target_bounds() const { return target_bounds_; }
+
+  views::Widget* item_widget() { return item_widget_.get(); }
+
   OverviewGrid* overview_grid() { return overview_grid_; }
 
   void set_should_animate_when_entering(bool should_animate) {
@@ -245,6 +242,7 @@
   }
 
  private:
+  friend class OverviewSessionRoundedCornerTest;
   friend class OverviewSessionTest;
   class OverviewCloseButton;
   class WindowSurfaceCacheObserver;
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc
index 2a98604a..07fbe4e 100644
--- a/ash/wm/overview/overview_session.cc
+++ b/ash/wm/overview/overview_session.cc
@@ -284,6 +284,10 @@
 // may cause other, unrelated classes, to make indirect calls to
 // restoring_minimized_windows() on a partially destructed object.
 void OverviewSession::Shutdown() {
+  // This should have been set already when the process of ending overview mode
+  // began. See OverviewController::OnSelectionEnded().
+  DCHECK(is_shutting_down_);
+
   Shell::Get()->RemovePreTargetHandler(this);
   Shell::Get()->RemoveShellObserver(this);
 
@@ -316,8 +320,10 @@
   // Setting focus after restoring windows' state avoids unnecessary animations.
   // No need to restore if we are sliding to the home launcher screen, as all
   // windows will be minimized.
-  ResetFocusRestoreWindow(enter_exit_overview_type_ ==
-                          EnterExitOverviewType::kNormal);
+  const bool should_focus =
+      enter_exit_overview_type_ == EnterExitOverviewType::kNormal ||
+      enter_exit_overview_type_ == EnterExitOverviewType::kImmediateExit;
+  ResetFocusRestoreWindow(should_focus);
   RemoveAllObservers();
 
   for (std::unique_ptr<OverviewGrid>& overview_grid : grid_list_)
@@ -332,6 +338,11 @@
   grid_list_.clear();
 
   if (no_windows_widget_) {
+    if (enter_exit_overview_type_ == EnterExitOverviewType::kImmediateExit) {
+      ImmediatelyCloseWidgetOnExit(std::move(no_windows_widget_));
+      return;
+    }
+
     // Fade out the no windows widget. This animation continues past the
     // lifetime of |this|.
     FadeOutWidgetAndMaybeSlideOnExit(std::move(no_windows_widget_),
@@ -462,6 +473,8 @@
   grid->AddItem(window, reposition, animate, ignored_items, index);
   ++num_items_;
 
+  MaybeCreateAndPositionNoWindowsWidget();
+
   // Transfer focus from |window| to |overview_focus_widget_| to match the
   // behavior of entering overview mode in the beginning.
   DCHECK(overview_focus_widget_);
@@ -493,6 +506,8 @@
       restore_focus_window_ = nullptr;
   }
 
+  MaybeCreateAndPositionNoWindowsWidget();
+
   GetGridWithOverviewItem(overview_item)->RemoveItem(overview_item);
   --num_items_;
 }
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h
index a96327ca..4bbff87 100644
--- a/ash/wm/overview/overview_session.h
+++ b/ash/wm/overview/overview_session.h
@@ -83,7 +83,12 @@
     // launcher does not animate in. On exit this mode is used to avoid the
     // update bounds animation of the windows in overview grid on overview mode
     // ended.
-    kWindowDragged
+    kWindowDragged,
+    // Used only when it's desired to exit overview mode immediately without
+    // animations. This is used when performing the desk switch animation when
+    // the source desk is in overview mode, while the target desk is not.
+    // This should not be used for entering overview mode.
+    kImmediateExit
   };
 
   // Callback which fills out the passed settings object. Used by several
@@ -264,6 +269,11 @@
 
   OverviewDelegate* delegate() { return delegate_; }
 
+  bool is_shutting_down() const { return is_shutting_down_; }
+  void set_is_shutting_down(bool is_shutting_down) {
+    is_shutting_down_ = is_shutting_down;
+  }
+
   SplitViewDragIndicators* split_view_drag_indicators() {
     return split_view_drag_indicators_.get();
   }
@@ -342,6 +352,9 @@
   // initially true until this is initialized.
   bool ignore_activations_ = true;
 
+  // True when overview mode is exiting.
+  bool is_shutting_down_ = false;
+
   // List of all the window overview grids, one for each root window.
   std::vector<std::unique_ptr<OverviewGrid>> grid_list_;
 
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc
index a03ad08..3dfb62f02 100644
--- a/ash/wm/overview/overview_session_unittest.cc
+++ b/ash/wm/overview/overview_session_unittest.cc
@@ -43,6 +43,7 @@
 #include "ash/wm/tablet_mode/tablet_mode_browser_window_drag_delegate.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_window_drag_controller.h"
+#include "ash/wm/window_preview_view.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
@@ -186,13 +187,6 @@
     overview_controller()->ToggleOverview(type);
   }
 
-  aura::Window* GetOverviewWindowForMinimizedState(int index,
-                                                   aura::Window* window) {
-    OverviewItem* item = GetWindowItemForWindow(index, window);
-    views::Widget* widget = minimized_widget(item);
-    return widget ? widget->GetNativeWindow() : nullptr;
-  }
-
   gfx::Rect GetTransformedBounds(aura::Window* window) {
     gfx::Rect bounds_in_screen = window->layer()->bounds();
     ::wm::ConvertRectToScreen(window->parent(), &bounds_in_screen);
@@ -305,6 +299,10 @@
     return item->caption_container_view_->backdrop_view();
   }
 
+  wm::WindowPreviewView* GetPreviewView(OverviewItem* item) {
+    return item->caption_container_view_->preview_view();
+  }
+
   // Tests that a window is contained within a given OverviewItem, and that both
   // the window and its matching close button are within the same screen.
   void CheckWindowAndCloseButtonInScreen(aura::Window* window,
@@ -332,10 +330,6 @@
     return item->item_widget_.get();
   }
 
-  views::Widget* minimized_widget(OverviewItem* item) {
-    return item->transform_window_.minimized_widget();
-  }
-
   const ScopedOverviewTransformWindow& transform_window(
       OverviewItem* item) const {
     return item->transform_window_;
@@ -476,13 +470,11 @@
   EXPECT_FALSE(window->IsVisible());
   EXPECT_EQ(0.f, window->layer()->GetTargetOpacity());
   EXPECT_EQ(mojom::WindowStateType::MINIMIZED, window_state->GetStateType());
-  aura::Window* window_for_minimized_window =
-      GetOverviewWindowForMinimizedState(0, window.get());
-  EXPECT_TRUE(window_for_minimized_window);
+  wm::WindowPreviewView* preview_view =
+      GetPreviewView(GetWindowItemForWindow(0, window.get()));
+  EXPECT_TRUE(preview_view);
 
-  const gfx::Point point =
-      GetTransformedBoundsInRootWindow(window_for_minimized_window)
-          .CenterPoint();
+  const gfx::Point point = preview_view->GetBoundsInScreen().CenterPoint();
   GetEventGenerator()->set_current_screen_location(point);
   GetEventGenerator()->ClickLeftButton();
 
@@ -734,12 +726,12 @@
   EXPECT_TRUE(widget->IsClosed());
   ASSERT_TRUE(IsSelecting());
 
-  aura::Window* window_for_minimized_window =
-      GetOverviewWindowForMinimizedState(0,
-                                         minimized_widget->GetNativeWindow());
-  ASSERT_TRUE(window_for_minimized_window);
+  aura::Window* minimized_window = minimized_widget->GetNativeWindow();
+  wm::WindowPreviewView* preview_view =
+      GetPreviewView(GetWindowItemForWindow(0, minimized_window));
+  EXPECT_TRUE(preview_view);
   const gfx::Point point2 =
-      GetCloseButton(GetWindowItemForWindow(0, window_for_minimized_window))
+      GetCloseButton(GetWindowItemForWindow(0, minimized_window))
           ->GetBoundsInScreen()
           .CenterPoint();
   GetEventGenerator()->MoveMouseTo(point2);
@@ -759,16 +751,16 @@
   aura::Window* window = widget->GetNativeWindow();
 
   ToggleOverview();
-  EXPECT_FALSE(GetOverviewWindowForMinimizedState(0, window));
+  EXPECT_FALSE(GetPreviewView(GetWindowItemForWindow(0, window)));
 
   widget->Minimize();
   EXPECT_TRUE(widget->IsMinimized());
   EXPECT_TRUE(IsSelecting());
-  EXPECT_TRUE(GetOverviewWindowForMinimizedState(0, window));
+  EXPECT_TRUE(GetPreviewView(GetWindowItemForWindow(0, window)));
 
   widget->Restore();
   EXPECT_FALSE(widget->IsMinimized());
-  EXPECT_FALSE(GetOverviewWindowForMinimizedState(0, window));
+  EXPECT_FALSE(GetPreviewView(GetWindowItemForWindow(0, window)));
   EXPECT_TRUE(IsSelecting());
 }
 
@@ -1738,6 +1730,20 @@
             no_windows_widget->GetWindowBoundsInScreen().CenterPoint());
 }
 
+// Tests that the no windows indicator shows properly after adding an item.
+TEST_F(OverviewSessionTest, NoWindowsIndicatorAddItem) {
+  std::unique_ptr<aura::Window> window(CreateTestWindow());
+
+  ToggleOverview();
+  auto* split_view_controller = Shell::Get()->split_view_controller();
+  split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT);
+  EXPECT_TRUE(overview_session()->no_windows_widget_for_testing());
+
+  overview_session()->AddItem(window.get(), /*reposition=*/true,
+                              /*animate=*/false);
+  EXPECT_FALSE(overview_session()->no_windows_widget_for_testing());
+}
+
 // Verify that when opening overview mode with multiple displays, the no items
 // indicator on the primary grid if there are no windows.
 TEST_F(OverviewSessionTest, NoWindowsIndicatorPositionMultiDisplay) {
@@ -2274,40 +2280,19 @@
   views::Widget* widget1 = item_widget(item1);
   views::Widget* widget2 = item_widget(item2);
   views::Widget* widget3 = item_widget(item3);
-  views::Widget* min_widget1 = minimized_widget(item1);
-  views::Widget* min_widget2 = minimized_widget(item2);
-  views::Widget* min_widget3 = minimized_widget(item3);
 
   // The original order of stacking is determined by the order the associated
-  // window was activated (created in this case). All widgets associated with
-  // minimized windows will be below non minimized windows, because a widget for
-  // the minimized windows is created upon entering overview, and they are
-  // explicitly stacked beneath non minimized windows so they do not cover them
-  // during enter animation.
+  // window was activated (created in this case).
   EXPECT_GT(IndexOf(widget3->GetNativeWindow(), parent),
-            IndexOf(widget1->GetNativeWindow(), parent));
-  EXPECT_GT(IndexOf(widget1->GetNativeWindow(), parent),
             IndexOf(widget2->GetNativeWindow(), parent));
+  EXPECT_GT(IndexOf(widget2->GetNativeWindow(), parent),
+            IndexOf(widget1->GetNativeWindow(), parent));
 
-  // Verify that only minimized windows have minimized widgets in overview.
-  EXPECT_FALSE(min_widget1);
-  ASSERT_TRUE(min_widget2);
-  EXPECT_FALSE(min_widget3);
-
-  // Verify both item widgets and minimized widgets are parented to the parent
-  // of the original windows.
-  EXPECT_EQ(parent, widget1->GetNativeWindow()->parent());
-  EXPECT_EQ(parent, widget2->GetNativeWindow()->parent());
-  EXPECT_EQ(parent, widget3->GetNativeWindow()->parent());
-  EXPECT_EQ(parent, min_widget2->GetNativeWindow()->parent());
-
-  // Verify that the item widget is stacked below the window if not minimized.
-  // Verify that the item widget is stacked below the minimized widget if
-  // minimized.
+  // Verify that the item widget is stacked below the window.
   EXPECT_LT(IndexOf(widget1->GetNativeWindow(), parent),
             IndexOf(window.get(), parent));
   EXPECT_LT(IndexOf(widget2->GetNativeWindow(), parent),
-            IndexOf(min_widget2->GetNativeWindow(), parent));
+            IndexOf(minimized.get(), parent));
   EXPECT_LT(IndexOf(widget3->GetNativeWindow(), parent),
             IndexOf(window3.get(), parent));
 
@@ -2341,9 +2326,10 @@
 
   // Verify the stacking order is same as before dragging started.
   EXPECT_GT(IndexOf(widget3->GetNativeWindow(), parent),
-            IndexOf(widget1->GetNativeWindow(), parent));
-  EXPECT_GT(IndexOf(widget1->GetNativeWindow(), parent),
             IndexOf(widget2->GetNativeWindow(), parent));
+  EXPECT_GT(IndexOf(widget2->GetNativeWindow(), parent),
+            IndexOf(widget1->GetNativeWindow(), parent));
+
   histogram_tester.ExpectTotalCount(
       "Ash.Overview.WindowDrag.PresentationTime.TabletMode", 2);
   histogram_tester.ExpectTotalCount(
@@ -2463,11 +2449,10 @@
 
   bool HasRoundedCorner(OverviewItem* item) {
     if (!UseShaderForRoundedCorner())
-      return HasMaskForItem(item);
-    const ui::Layer* layer =
-        minimized_widget(item)
-            ? minimized_widget(item)->GetNativeWindow()->layer()
-            : transform_window(item).window()->layer();
+      return HasMaskForItem(item) || item->transform_window_.IsMinimized();
+    const ui::Layer* layer = item->transform_window_.IsMinimized()
+                                 ? GetPreviewView(item)->layer()
+                                 : transform_window(item).window()->layer();
     const std::array<uint32_t, 4>& radii = layer->rounded_corner_radii();
     return (radii[0] + radii[1] + radii[2] + radii[3]) > 0;
   }
@@ -2521,12 +2506,12 @@
   item2 = GetWindowItemForWindow(0, window2.get());
   EXPECT_FALSE(HasRoundedCorner(item1));
   EXPECT_FALSE(HasRoundedCorner(item2));
-  minimized_widget(item1)
+  item_widget(item1)
       ->GetNativeWindow()
       ->layer()
       ->GetAnimator()
       ->StopAnimating();
-  minimized_widget(item2)
+  item_widget(item2)
       ->GetNativeWindow()
       ->layer()
       ->GetAnimator()
diff --git a/ash/wm/overview/overview_utils.cc b/ash/wm/overview/overview_utils.cc
index 6fb7d4ba..2d7b34f 100644
--- a/ash/wm/overview/overview_utils.cc
+++ b/ash/wm/overview/overview_utils.cc
@@ -22,7 +22,6 @@
 #include "ash/wm/window_transient_descendant_iterator.h"
 #include "ash/wm/wm_event.h"
 #include "base/no_destructor.h"
-#include "third_party/skia/include/pathops/SkPathOps.h"
 #include "ui/aura/window.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/scoped_canvas.h"
@@ -56,7 +55,8 @@
 
 void FadeInWidgetAndMaybeSlideOnEnter(views::Widget* widget,
                                       OverviewAnimationType animation_type,
-                                      bool slide) {
+                                      bool slide,
+                                      bool observe) {
   aura::Window* window = widget->GetNativeWindow();
   if (window->layer()->GetTargetOpacity() == 1.f && !slide)
     return;
@@ -76,9 +76,10 @@
   ScopedOverviewAnimationSettings scoped_overview_animation_settings(
       animation_type, window);
   window->layer()->SetOpacity(1.0f);
-  if (slide) {
+  if (slide)
     window->SetTransform(original_transform);
 
+  if (observe) {
     auto enter_observer = std::make_unique<EnterAnimationObserver>();
     scoped_overview_animation_settings.AddObserver(enter_observer.get());
     Shell::Get()->overview_controller()->AddEnterAnimationObserver(
@@ -118,6 +119,12 @@
   }
 }
 
+void ImmediatelyCloseWidgetOnExit(std::unique_ptr<views::Widget> widget) {
+  ScopedAnimationDisabler animation_disabler(widget->GetNativeWindow());
+  widget->Close();
+  widget.reset();
+}
+
 wm::WindowTransientDescendantIteratorRange GetVisibleTransientTreeIterator(
     aura::Window* window) {
   auto hide_predicate = [](aura::Window* window) {
diff --git a/ash/wm/overview/overview_utils.h b/ash/wm/overview/overview_utils.h
index 48ce638..611173e7 100644
--- a/ash/wm/overview/overview_utils.h
+++ b/ash/wm/overview/overview_utils.h
@@ -30,10 +30,12 @@
 
 // Fades |widget| to opacity one with the enter overview settings. Additionally
 // place |widget| closer to the top of screen and slide it down if |slide| is
-// true.
+// true. Have OverviewController observe this animation as a enter animation if
+// |observe| is true.
 void FadeInWidgetAndMaybeSlideOnEnter(views::Widget* widget,
                                       OverviewAnimationType animation_type,
-                                      bool slide);
+                                      bool slide,
+                                      bool observe);
 
 // Fades |widget| to opacity zero with animation settings depending on
 // |animation_type|. Used by several classes which need to be destroyed on
@@ -42,6 +44,9 @@
 void FadeOutWidgetAndMaybeSlideOnExit(std::unique_ptr<views::Widget> widget,
                                       OverviewAnimationType animation_type);
 
+// Takes ownership of |widget|, closes and destroys it without any animations.
+void ImmediatelyCloseWidgetOnExit(std::unique_ptr<views::Widget> widget);
+
 // Iterates through all the windows in the transient tree associated with
 // |window| that are visible.
 wm::WindowTransientDescendantIteratorRange GetVisibleTransientTreeIterator(
diff --git a/ash/wm/overview/rounded_label_widget.cc b/ash/wm/overview/rounded_label_widget.cc
index 2b01ec3..9a50ce4 100644
--- a/ash/wm/overview/rounded_label_widget.cc
+++ b/ash/wm/overview/rounded_label_widget.cc
@@ -94,13 +94,17 @@
   Show();
 }
 
-void RoundedLabelWidget::SetBoundsCenteredIn(const gfx::Rect& bounds) {
+gfx::Rect RoundedLabelWidget::GetBoundsCenteredIn(const gfx::Rect& bounds) {
   DCHECK(GetContentsView());
   RoundedLabelView* contents_view =
       static_cast<RoundedLabelView*>(GetContentsView());
   gfx::Rect widget_bounds = bounds;
   widget_bounds.ClampToCenteredSize(contents_view->GetPreferredSize());
-  GetNativeWindow()->SetBounds(widget_bounds);
+  return widget_bounds;
+}
+
+void RoundedLabelWidget::SetBoundsCenteredIn(const gfx::Rect& bounds) {
+  GetNativeWindow()->SetBounds(GetBoundsCenteredIn(bounds));
 }
 
 }  // namespace ash
diff --git a/ash/wm/overview/rounded_label_widget.h b/ash/wm/overview/rounded_label_widget.h
index cea7ab28..67b6a35 100644
--- a/ash/wm/overview/rounded_label_widget.h
+++ b/ash/wm/overview/rounded_label_widget.h
@@ -32,6 +32,10 @@
   ~RoundedLabelWidget() override;
 
   void Init(const InitParams& params);
+
+  // Gets the preferred size of the widget centered in |bounds|.
+  gfx::Rect GetBoundsCenteredIn(const gfx::Rect& bounds);
+
   // Places the widget in the middle of |bounds|. The size will be the preferred
   // size of the label.
   void SetBoundsCenteredIn(const gfx::Rect& bounds);
diff --git a/ash/wm/overview/scoped_overview_transform_window.cc b/ash/wm/overview/scoped_overview_transform_window.cc
index f92c086..6ebf24ce 100644
--- a/ash/wm/overview/scoped_overview_transform_window.cc
+++ b/ash/wm/overview/scoped_overview_transform_window.cc
@@ -226,20 +226,13 @@
   return transform;
 }
 
-void ScopedOverviewTransformWindow::RestoreWindow(
-    bool reset_transform,
-    OverviewSession::EnterExitOverviewType type) {
+void ScopedOverviewTransformWindow::RestoreWindow(bool reset_transform) {
   // Shadow controller may be null on shutdown.
   if (Shell::Get()->shadow_controller())
     Shell::Get()->shadow_controller()->UpdateShadowForWindow(window_);
-  if (minimized_widget_) {
-    // Fade out the minimized widget. This animation continues past the
-    // lifetime of |this|.
-    FadeOutWidgetAndMaybeSlideOnExit(
-        std::move(minimized_widget_),
-        GetExitOverviewAnimationTypeForMinimizedWindow(type));
+
+  if (IsMinimized())
     return;
-  }
 
   if (reset_transform) {
     ScopedAnimationSettings animation_settings_list;
@@ -254,7 +247,7 @@
 
     // Use identity transform directly to reset window's transform when exiting
     // overview.
-    SetTransform(GetOverviewWindow(), gfx::Transform());
+    SetTransform(window_, gfx::Transform());
     // Add requests to cache render surface and perform trilinear filtering for
     // the exit animation of overview mode. The requests will be removed when
     // the exit animation finishes.
@@ -278,7 +271,7 @@
   if (animation_type == OVERVIEW_ANIMATION_NONE)
     return;
 
-  for (auto* window : GetVisibleTransientTreeIterator(GetOverviewWindow())) {
+  for (auto* window : GetVisibleTransientTreeIterator(window_)) {
     auto settings = std::make_unique<ScopedOverviewAnimationSettings>(
         animation_type, window);
     settings->DeferPaint();
@@ -307,18 +300,18 @@
       return true;
   }
 
-  if (!minimized_widget_)
+  if (!IsMinimized())
     return false;
-  return minimized_widget_->GetNativeWindow()->Contains(target);
+  return overview_item_->item_widget()->GetNativeWindow()->Contains(target);
 }
 
 gfx::RectF ScopedOverviewTransformWindow::GetTransformedBounds() const {
-  return ::ash::GetTransformedBounds(GetOverviewWindow(), GetTopInset());
+  return ::ash::GetTransformedBounds(window_, GetTopInset());
 }
 
 int ScopedOverviewTransformWindow::GetTopInset() const {
   // Mirror window doesn't have insets.
-  if (minimized_widget_)
+  if (IsMinimized())
     return 0;
   for (auto* window : GetVisibleTransientTreeIterator(window_)) {
     // If there are regular windows in the transient ancestor tree, all those
@@ -340,21 +333,6 @@
     window->layer()->SetOpacity(opacity);
 }
 
-void ScopedOverviewTransformWindow::UpdateMirrorWindowForMinimizedState() {
-  // TODO(oshima): Disable animation.
-  if (window_->GetProperty(aura::client::kShowStateKey) ==
-      ui::SHOW_STATE_MINIMIZED) {
-    if (!minimized_widget_)
-      CreateMirrorWindowForMinimizedState();
-  } else {
-    // If the original window is no longer minimized, make sure it will be
-    // visible when we restore it when selection mode ends.
-    EnsureVisible();
-    minimized_widget_->CloseNow();
-    minimized_widget_.reset();
-  }
-}
-
 gfx::RectF ScopedOverviewTransformWindow::ShrinkRectToFitPreservingAspectRatio(
     const gfx::RectF& rect,
     const gfx::RectF& bounds,
@@ -409,6 +387,12 @@
   return new_bounds;
 }
 
+aura::Window* ScopedOverviewTransformWindow::GetOverviewWindow() const {
+  if (IsMinimized())
+    return overview_item_->item_widget()->GetNativeWindow();
+  return window_;
+}
+
 void ScopedOverviewTransformWindow::Close() {
   if (immediate_close_for_tests) {
     CloseWidget();
@@ -422,15 +406,15 @@
       base::TimeDelta::FromMilliseconds(kCloseWindowDelayInMilliseconds));
 }
 
+bool ScopedOverviewTransformWindow::IsMinimized() const {
+  return wm::GetWindowState(window_)->IsMinimized();
+}
+
 void ScopedOverviewTransformWindow::PrepareForOverview() {
   Shell::Get()->shadow_controller()->UpdateShadowForWindow(window_);
 
   DCHECK(!overview_started_);
   overview_started_ = true;
-  if (window_->GetProperty(aura::client::kShowStateKey) ==
-      ui::SHOW_STATE_MINIMIZED) {
-    CreateMirrorWindowForMinimizedState();
-  }
 
   // Add requests to cache render surface and perform trilinear filtering. The
   // requests will be removed in dtor. So the requests will be valid during the
@@ -455,12 +439,6 @@
   immediate_close_for_tests = true;
 }
 
-aura::Window* ScopedOverviewTransformWindow::GetOverviewWindow() const {
-  if (minimized_widget_)
-    return minimized_widget_->GetNativeWindow();
-  return window_;
-}
-
 void ScopedOverviewTransformWindow::EnsureVisible() {
   original_opacity_ = 1.f;
 }
@@ -471,11 +449,13 @@
 }
 
 void ScopedOverviewTransformWindow::UpdateMask(bool show) {
+  // Minimized windows have their corners rounded in CaptionContainerView.
+  if (IsMinimized())
+    return;
+
   // Add the mask which gives the overview item rounded corners, and add the
   // shadow around the window.
-  ui::Layer* layer = minimized_widget_
-                         ? minimized_widget_->GetNativeWindow()->layer()
-                         : window_->layer();
+  ui::Layer* layer = window_->layer();
   if (ash::features::ShouldUseShaderRoundedCorner()) {
     const float scale = layer->transform().Scale2d().x();
     static constexpr std::array<uint32_t, 4> kEmptyRadii = {0, 0, 0, 0};
@@ -486,12 +466,14 @@
     layer->SetIsFastRoundedCorner(true);
     return;
   }
+
   if (!base::FeatureList::IsEnabled(features::kEnableOverviewRoundedCorners) ||
       !show) {
     mask_.reset();
     return;
   }
-  mask_ = std::make_unique<WindowMask>(GetOverviewWindow());
+
+  mask_ = std::make_unique<WindowMask>(window_);
   mask_->layer()->SetBounds(layer->bounds());
   mask_->set_top_inset(GetTopInset());
   layer->SetMaskLayer(mask_->layer());
@@ -501,34 +483,6 @@
   StopObservingImplicitAnimations();
 }
 
-void ScopedOverviewTransformWindow::ResizeMinimizedWidgetIfNeeded() {
-  if (!minimized_widget_)
-    return;
-
-  gfx::Rect bounds(window_->GetBoundsInScreen());
-  if (bounds.size() == window_->GetBoundsInScreen().size())
-    return;
-
-  auto* preview_view =
-      static_cast<wm::WindowPreviewView*>(minimized_widget_->GetContentsView());
-  if (preview_view) {
-    preview_view->RecreatePreviews();
-    bounds.Inset(0, 0, 0,
-                 bounds.height() - preview_view->GetPreferredSize().height());
-    minimized_widget_->SetBounds(bounds);
-  }
-}
-
-void ScopedOverviewTransformWindow::UpdateMinimizedWidget() {
-  if (!minimized_widget_)
-    return;
-
-  wm::WindowPreviewView* preview_view =
-      new wm::WindowPreviewView(window_, /*trilinear_filtering_on_init=*/false);
-  preview_view->SetVisible(true);
-  minimized_widget_->SetContentsView(preview_view);
-}
-
 void ScopedOverviewTransformWindow::OnLayerAnimationStarted(
     ui::LayerAnimationSequence* sequence) {
   // Remove the mask before animating because masks affect animation
@@ -547,66 +501,4 @@
   return mask_->layer()->bounds();
 }
 
-void ScopedOverviewTransformWindow::CreateMirrorWindowForMinimizedState() {
-  DCHECK(!minimized_widget_.get());
-  views::Widget::InitParams params;
-  params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
-  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
-  params.visible_on_all_workspaces = true;
-  params.name = "OverviewModeMinimized";
-  params.activatable = views::Widget::InitParams::Activatable::ACTIVATABLE_NO;
-  params.accept_events = false;
-  params.parent = window_->parent();
-  minimized_widget_ = std::make_unique<views::Widget>();
-  minimized_widget_->set_focus_on_creation(false);
-  minimized_widget_->Init(params);
-
-  // Trilinear filtering will be applied on the |minimized_widget_| in
-  // PrepareForOverview() and RestoreWindow().
-  wm::WindowPreviewView* mirror_view =
-      new wm::WindowPreviewView(window_, /*trilinear_filtering_on_init=*/false);
-  mirror_view->SetVisible(true);
-  minimized_widget_->SetContentsView(mirror_view);
-  gfx::Rect bounds(window_->GetBoundsInScreen());
-  gfx::Size preferred = mirror_view->GetPreferredSize();
-  // In unit tests, the content view can have empty size.
-  if (!preferred.IsEmpty()) {
-    int inset = bounds.height() - preferred.height();
-    bounds.Inset(0, 0, 0, inset);
-  }
-  minimized_widget_->SetBounds(bounds);
-  minimized_widget_->SetVisibilityAnimationTransition(
-      views::Widget::ANIMATE_NONE);
-  minimized_widget_->Show();
-  minimized_widget_->SetOpacity(0.f);
-
-  // Stack the minimized window at the bottom since it is never transformed in
-  // and only faded in, so it should always be underneath non minimized windows.
-  window_->parent()->StackChildAtBottom(minimized_widget_->GetNativeWindow());
-
-  FadeInWidgetAndMaybeSlideOnEnter(
-      minimized_widget_.get(), OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
-      /*slide=*/false);
-}
-
-OverviewAnimationType
-ScopedOverviewTransformWindow::GetExitOverviewAnimationTypeForMinimizedWindow(
-    OverviewSession::EnterExitOverviewType type) {
-  // EnterExitOverviewType can only be set to kWindowMinimized in talbet mode.
-  // Fade out the minimized window without animation if switch from tablet mode
-  // to clamshell mode.
-  if (type == OverviewSession::EnterExitOverviewType::kWindowsMinimized) {
-    return Shell::Get()
-                   ->tablet_mode_controller()
-                   ->IsTabletModeWindowManagerEnabled()
-               ? OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER
-               : OVERVIEW_ANIMATION_NONE;
-  }
-
-  DCHECK(overview_item_);
-  return overview_item_->should_animate_when_exiting()
-             ? OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT
-             : OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO;
-}
-
 }  // namespace ash
diff --git a/ash/wm/overview/scoped_overview_transform_window.h b/ash/wm/overview/scoped_overview_transform_window.h
index e5f0fa0..fd400d4 100644
--- a/ash/wm/overview/scoped_overview_transform_window.h
+++ b/ash/wm/overview/scoped_overview_transform_window.h
@@ -29,10 +29,6 @@
 class Layer;
 }
 
-namespace views {
-class Widget;
-}
-
 namespace ash {
 class OverviewItem;
 class ScopedOverviewAnimationSettings;
@@ -110,8 +106,7 @@
   // If |reset_transform| equals false, the window's transform will not be reset
   // to identity transform when exiting the overview mode. See
   // OverviewItem::RestoreWindow() for details why we need this.
-  void RestoreWindow(bool reset_transform,
-                     OverviewSession::EnterExitOverviewType type);
+  void RestoreWindow(bool reset_transform);
 
   // Informs the ScopedOverviewTransformWindow that the window being watched was
   // destroyed. This resets the internal window pointer.
@@ -123,9 +118,6 @@
   // Sets the opacity of the managed windows.
   void SetOpacity(float opacity);
 
-  // Creates/Deletes a mirror window for minimized windows.
-  void UpdateMirrorWindowForMinimizedState();
-
   // Returns |rect| having been shrunk to fit within |bounds| (preserving the
   // aspect ratio). Takes into account a window header that is |top_view_inset|
   // tall in the original window getting replaced by a window caption that is
@@ -136,20 +128,14 @@
                                                   int top_view_inset,
                                                   int title_height);
 
-  aura::Window* window() const { return window_; }
-
-  GridWindowFillMode type() const { return type_; }
-
-  base::Optional<gfx::RectF> overview_bounds() const {
-    return overview_bounds_;
-  }
+  // Returns the window used to show the content in overview mode.
+  // For minimized window this will be a window that hosts mirrored layers.
+  aura::Window* GetOverviewWindow() const;
 
   // Closes the transient root of the window managed by |this|.
   void Close();
 
-  // Returns the window used to show the content in overview mode.
-  // For minimized window this will be a window that hosts mirrored layers.
-  aura::Window* GetOverviewWindow() const;
+  bool IsMinimized() const;
 
   // Ensures that a window is visible by setting its opacity to 1.
   void EnsureVisible();
@@ -165,19 +151,18 @@
   // Stop listening to any animations to finish.
   void CancelAnimationsListener();
 
-  // If the original window is minimized, resize |minimized_widget_| to match
-  // the bounds of the |window_|.
-  void ResizeMinimizedWidgetIfNeeded();
-
-  // Update |minimized_widget_| so that its content view is up-to-date.
-  void UpdateMinimizedWidget();
-
-  views::Widget* minimized_widget() { return minimized_widget_.get(); }
-
   // ui::ImplicitAnimationObserver:
   void OnLayerAnimationStarted(ui::LayerAnimationSequence* sequence) override;
   void OnImplicitAnimationsCompleted() override;
 
+  aura::Window* window() const { return window_; }
+
+  GridWindowFillMode type() const { return type_; }
+
+  base::Optional<gfx::RectF> overview_bounds() const {
+    return overview_bounds_;
+  }
+
   gfx::Rect GetMaskBoundsForTesting() const;
 
  private:
@@ -190,15 +175,11 @@
   // Closes the window managed by |this|.
   void CloseWidget();
 
-  void CreateMirrorWindowForMinimizedState();
-
-  OverviewAnimationType GetExitOverviewAnimationTypeForMinimizedWindow(
-      OverviewSession::EnterExitOverviewType type);
-
   // Makes Close() execute synchronously when used in tests.
   static void SetImmediateCloseForTests();
 
-  // A weak pointer to the overview item that owns the transform window.
+  // A weak pointer to the overview item that owns |this|. Guaranteed to be not
+  // null for the lifetime of |this|.
   OverviewItem* overview_item_;
 
   // A weak pointer to the real window in the overview.
@@ -222,9 +203,6 @@
   // should be if the window is too wide or too tall.
   base::Optional<gfx::RectF> overview_bounds_;
 
-  // A widget that holds the content for the minimized window.
-  std::unique_ptr<views::Widget> minimized_widget_;
-
   // The observers associated with the layers we requested caching render
   // surface and trilinear filtering. The requests will be removed in dtor if
   // the layer has not been destroyed.
diff --git a/base/memory/memory_pressure_monitor_notifying_chromeos.cc b/base/memory/memory_pressure_monitor_notifying_chromeos.cc
index 139da40..1cd8c91 100644
--- a/base/memory/memory_pressure_monitor_notifying_chromeos.cc
+++ b/base/memory/memory_pressure_monitor_notifying_chromeos.cc
@@ -28,13 +28,13 @@
 namespace chromeos {
 
 namespace {
-// Type-safe version of |g_monitor| from base/memory/memory_pressure_monitor.cc,
-// this was originally added because TabManagerDelegate for chromeos needs to
-// call into ScheduleEarlyCheck which isn't a public API in the base
-// MemoryPressureMonitor. This matters because ChromeOS may create a
-// FakeMemoryPressureMonitor for browser tests and that's why this type-specific
-// version was added.
-MemoryPressureMonitorNotifying* g_monitor = nullptr;
+// Type-safe version of |g_monitor_notifying| from
+// base/memory/memory_pressure_monitor.cc, this was originally added because
+// TabManagerDelegate for chromeos needs to call into ScheduleEarlyCheck which
+// isn't a public API in the base MemoryPressureMonitor. This matters because
+// ChromeOS may create a FakeMemoryPressureMonitor for browser tests and that's
+// why this type-specific version was added.
+MemoryPressureMonitorNotifying* g_monitor_notifying = nullptr;
 
 // We try not to re-notify on moderate too frequently, this time
 // controls how frequently we will notify after our first notification.
@@ -132,8 +132,8 @@
           base::BindRepeating(std::move(kernel_waiting_callback),
                               available_mem_file_.get())),
       weak_ptr_factory_(this) {
-  DCHECK(g_monitor == nullptr);
-  g_monitor = this;
+  DCHECK(g_monitor_notifying == nullptr);
+  g_monitor_notifying = this;
 
   CHECK(available_mem_file_.is_valid());
   std::vector<int> margin_parts =
@@ -160,8 +160,8 @@
 }
 
 MemoryPressureMonitorNotifying::~MemoryPressureMonitorNotifying() {
-  DCHECK(g_monitor);
-  g_monitor = nullptr;
+  DCHECK(g_monitor_notifying);
+  g_monitor_notifying = nullptr;
 }
 
 std::vector<int> MemoryPressureMonitorNotifying::GetMarginFileParts() {
@@ -305,7 +305,7 @@
 
 // static
 MemoryPressureMonitorNotifying* MemoryPressureMonitorNotifying::Get() {
-  return g_monitor;
+  return g_monitor_notifying;
 }
 
 }  // namespace chromeos
diff --git a/base/task/thread_pool/initialization_util.cc b/base/task/thread_pool/initialization_util.cc
index 7534eb37..d70c4c3d 100644
--- a/base/task/thread_pool/initialization_util.cc
+++ b/base/task/thread_pool/initialization_util.cc
@@ -10,10 +10,10 @@
 
 namespace base {
 
-int RecommendedMaxNumberOfThreadsInPool(int min,
-                                        int max,
-                                        double cores_multiplier,
-                                        int offset) {
+int RecommendedMaxNumberOfThreadsInThreadGroup(int min,
+                                               int max,
+                                               double cores_multiplier,
+                                               int offset) {
   const int num_of_cores = SysInfo::NumberOfProcessors();
   const int threads = std::ceil<int>(num_of_cores * cores_multiplier) + offset;
   return std::min(max, std::max(min, threads));
diff --git a/base/task/thread_pool/initialization_util.h b/base/task/thread_pool/initialization_util.h
index c81438e..62486f2e 100644
--- a/base/task/thread_pool/initialization_util.h
+++ b/base/task/thread_pool/initialization_util.h
@@ -10,11 +10,12 @@
 namespace base {
 
 // Computes a value that may be used as the maximum number of threads in a
-// ThreadPool pool. Developers may use other methods to choose this maximum.
-BASE_EXPORT int RecommendedMaxNumberOfThreadsInPool(int min,
-                                                    int max,
-                                                    double cores_multiplier,
-                                                    int offset);
+// ThreadGroup. Developers may use other methods to choose this maximum.
+BASE_EXPORT int RecommendedMaxNumberOfThreadsInThreadGroup(
+    int min,
+    int max,
+    double cores_multiplier,
+    int offset);
 
 }  // namespace base
 
diff --git a/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc b/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
index 6d2eec83..2fa3523 100644
--- a/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
+++ b/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
@@ -240,7 +240,27 @@
     //   have work:
     //   Process task sources from each source round-robin style.
     CheckedAutoLock auto_lock(lock_);
-    DCHECK(worker_awake_);
+
+    // |worker_awake_| is always set before a call to WakeUp(), but it is
+    // not set when messages are added to the Windows Message Queue. Ensure that
+    // it is set before getting work, to avoid unnecessary wake ups.
+    //
+    // Note: It wouldn't be sufficient to set |worker_awake_| in WaitForWork()
+    // when MsgWaitForMultipleObjectsEx() indicates that it was woken up by a
+    // Windows Message, because of the following scenario:
+    //  T1: PostTask
+    //      Queue task
+    //      Set |worker_awake_| to true
+    //  T2: Woken up by a Windows Message
+    //      Set |worker_awake_| to true
+    //      Run the task posted by T1
+    //      Wait for work
+    //  T1: WakeUp()
+    //  T2: Woken up by Waitable Event
+    //      Does not set |worker_awake_| (wake up not from Windows Message)
+    //      GetWork
+    //      !! Getting work while |worker_awake_| is false !!
+    worker_awake_ = true;
     scoped_refptr<TaskSource> task_source;
     if (get_work_first_) {
       task_source = WorkerThreadDelegate::GetWorkLockRequired(worker);
@@ -279,12 +299,8 @@
     const DWORD milliseconds_wait = checked_cast<DWORD>(
         sleep_time.is_max() ? INFINITE : sleep_time.InMilliseconds());
     const HANDLE wake_up_event_handle = wake_up_event->handle();
-    DWORD reason = MsgWaitForMultipleObjectsEx(
-        1, &wake_up_event_handle, milliseconds_wait, QS_ALLINPUT, 0);
-    if (reason != WAIT_OBJECT_0) {
-      CheckedAutoLock auto_lock(lock_);
-      worker_awake_ = true;
-    }
+    MsgWaitForMultipleObjectsEx(1, &wake_up_event_handle, milliseconds_wait,
+                                QS_ALLINPUT, 0);
   }
 
  private:
diff --git a/base/task/thread_pool/pooled_single_thread_task_runner_manager.h b/base/task/thread_pool/pooled_single_thread_task_runner_manager.h
index 14f62ec0..17c8348 100644
--- a/base/task/thread_pool/pooled_single_thread_task_runner_manager.h
+++ b/base/task/thread_pool/pooled_single_thread_task_runner_manager.h
@@ -38,7 +38,7 @@
 
 }  // namespace
 
-// Manages a pool of threads which are each associated with one or more
+// Manages a group of threads which are each associated with one or more
 // SingleThreadTaskRunners.
 //
 // SingleThreadTaskRunners using SingleThreadTaskRunnerThreadMode::SHARED are
diff --git a/base/task/thread_pool/pooled_task_runner_delegate.h b/base/task/thread_pool/pooled_task_runner_delegate.h
index dace20e..967697b 100644
--- a/base/task/thread_pool/pooled_task_runner_delegate.h
+++ b/base/task/thread_pool/pooled_task_runner_delegate.h
@@ -34,15 +34,14 @@
                                     scoped_refptr<Sequence> sequence) = 0;
 
   // Invoked when RunsTasksInCurrentSequence() is called on a
-  // PooledParallelTaskRunner. Returns true if the worker pool used by the
-  // PooledParallelTaskRunner (as determined by |traits|) is running on
-  // this thread.
+  // PooledParallelTaskRunner. Returns true if the current thread is part of the
+  // ThreadGroup associated with |traits|.
   virtual bool IsRunningPoolWithTraits(const TaskTraits& traits) const = 0;
 
   // Invoked when the priority of |sequence|'s TaskRunner is updated. The
   // implementation must update |sequence|'s priority to |priority|, then place
   // |sequence| in the correct priority-queue position within the appropriate
-  // worker pool.
+  // thread group.
   virtual void UpdatePriority(scoped_refptr<TaskSource> task_source,
                               TaskPriority priority) = 0;
 };
diff --git a/base/task/thread_pool/service_thread.cc b/base/task/thread_pool/service_thread.cc
index 40ccddf..5aad89e9 100644
--- a/base/task/thread_pool/service_thread.cc
+++ b/base/task/thread_pool/service_thread.cc
@@ -79,8 +79,8 @@
   // Only record latency for one set of TaskTraits per report to avoid bias in
   // the order in which tasks are posted (should we record all at once) as well
   // as to avoid spinning up many worker threads to process this report if the
-  // thread pool is currently idle (each pool keeps at least one idle thread so
-  // a single task isn't an issue).
+  // thread pool is currently idle (each thread group keeps at least one idle
+  // thread so a single task isn't an issue).
 
   // Invoke RandInt() out-of-line to ensure it's obtained before
   // TimeTicks::Now().
diff --git a/base/task/thread_pool/task_tracker.cc b/base/task/thread_pool/task_tracker.cc
index b258169..31f5991 100644
--- a/base/task/thread_pool/task_tracker.cc
+++ b/base/task/thread_pool/task_tracker.cc
@@ -38,7 +38,7 @@
         static_cast<size_t>(TaskSourceExecutionMode::kMax) + 1,
     "Array kExecutionModeString is out of sync with TaskSourceExecutionMode.");
 
-// An immutable copy of a scheduler task's info required by tracing.
+// An immutable copy of a thread pool task's info required by tracing.
 class TaskTracingInfo : public trace_event::ConvertableToTraceFormat {
  public:
   TaskTracingInfo(const TaskTraits& task_traits,
diff --git a/base/task/thread_pool/test_utils.cc b/base/task/thread_pool/test_utils.cc
index 77c9da3..bf26d68 100644
--- a/base/task/thread_pool/test_utils.cc
+++ b/base/task/thread_pool/test_utils.cc
@@ -90,7 +90,7 @@
 }
 
 // Waits on |event| in a scope where the blocking observer is null, to avoid
-// affecting the max tasks in a worker pool.
+// affecting the max tasks in a thread group.
 void WaitWithoutBlockingObserver(WaitableEvent* event) {
   internal::ScopedClearBlockingObserverForTesting clear_blocking_observer;
   ScopedAllowBaseSyncPrimitivesForTesting allow_base_sync_primitives;
diff --git a/base/task/thread_pool/test_utils.h b/base/task/thread_pool/test_utils.h
index 7a168a0..2386ecda 100644
--- a/base/task/thread_pool/test_utils.h
+++ b/base/task/thread_pool/test_utils.h
@@ -73,7 +73,7 @@
 // TODO(etiennep): Migrate to TaskSourceExecutionMode.
 enum class ExecutionMode { PARALLEL, SEQUENCED, SINGLE_THREADED };
 
-// An enumeration of possible pool types. Used to parametrize relevant
+// An enumeration of possible thread pool types. Used to parametrize relevant
 // thread_pool tests.
 enum class PoolType {
   GENERIC,
@@ -92,9 +92,8 @@
     TaskSourceExecutionMode execution_mode =
         TaskSourceExecutionMode::kParallel);
 
-// Creates a TaskRunner that posts tasks to the worker pool owned by
-// |pooled_task_runner_delegate| with the |execution_mode| execution mode
-// and the WithBaseSyncPrimitives() trait.
+// Creates a TaskRunner that posts tasks to the thread group owned by
+// |pooled_task_runner_delegate| with the |execution_mode|.
 // Caveat: this does not support ExecutionMode::SINGLE_THREADED.
 scoped_refptr<TaskRunner> CreateTaskRunnerWithExecutionMode(
     test::ExecutionMode execution_mode,
diff --git a/base/task/thread_pool/thread_group.cc b/base/task/thread_pool/thread_group.cc
index a640be9..4ae9473e 100644
--- a/base/task/thread_pool/thread_group.cc
+++ b/base/task/thread_pool/thread_group.cc
@@ -30,8 +30,8 @@
 ThreadGroup::ScopedReenqueueExecutor::ScopedReenqueueExecutor() = default;
 
 ThreadGroup::ScopedReenqueueExecutor::~ScopedReenqueueExecutor() {
-  if (destination_pool_) {
-    destination_pool_->PushTaskSourceAndWakeUpWorkers(
+  if (destination_thread_group_) {
+    destination_thread_group_->PushTaskSourceAndWakeUpWorkers(
         std::move(task_source_and_transaction_.value()));
   }
 }
@@ -39,20 +39,21 @@
 void ThreadGroup::ScopedReenqueueExecutor::
     SchedulePushTaskSourceAndWakeUpWorkers(
         TaskSourceAndTransaction task_source_and_transaction,
-        ThreadGroup* destination_pool) {
-  DCHECK(destination_pool);
-  DCHECK(!destination_pool_);
+        ThreadGroup* destination_thread_group) {
+  DCHECK(destination_thread_group);
+  DCHECK(!destination_thread_group_);
   DCHECK(!task_source_and_transaction_);
   task_source_and_transaction_.emplace(std::move(task_source_and_transaction));
-  destination_pool_ = destination_pool;
+  destination_thread_group_ = destination_thread_group;
 }
 
 ThreadGroup::ThreadGroup(TrackedRef<TaskTracker> task_tracker,
                          TrackedRef<Delegate> delegate,
-                         ThreadGroup* predecessor_pool)
+                         ThreadGroup* predecessor_thread_group)
     : task_tracker_(std::move(task_tracker)),
       delegate_(std::move(delegate)),
-      lock_(predecessor_pool ? &predecessor_pool->lock_ : nullptr) {
+      lock_(predecessor_thread_group ? &predecessor_thread_group->lock_
+                                     : nullptr) {
   DCHECK(task_tracker_);
 }
 
@@ -121,20 +122,20 @@
     BaseScopedWorkersExecutor* workers_executor,
     ScopedReenqueueExecutor* reenqueue_executor,
     TaskSourceAndTransaction task_source_and_transaction) {
-  // Decide in which pool the TaskSource should be reenqueued.
-  ThreadGroup* destination_pool = delegate_->GetThreadGroupForTraits(
+  // Decide in which thread group the TaskSource should be reenqueued.
+  ThreadGroup* destination_thread_group = delegate_->GetThreadGroupForTraits(
       task_source_and_transaction.transaction.traits());
 
-  if (destination_pool == this) {
-    // If the TaskSource should be reenqueued in the current pool, reenqueue it
-    // inside the scope of the lock.
+  if (destination_thread_group == this) {
+    // If the TaskSource should be reenqueued in the current thread group,
+    // reenqueue it inside the scope of the lock.
     priority_queue_.Push(std::move(task_source_and_transaction.task_source),
                          task_source_and_transaction.transaction.GetSortKey());
     EnsureEnoughWorkersLockRequired(workers_executor);
   } else {
     // Otherwise, schedule a reenqueue after releasing the lock.
     reenqueue_executor->SchedulePushTaskSourceAndWakeUpWorkers(
-        std::move(task_source_and_transaction), destination_pool);
+        std::move(task_source_and_transaction), destination_thread_group);
   }
 }
 
@@ -150,18 +151,19 @@
     BaseScopedWorkersExecutor* executor,
     TaskSourceAndTransaction task_source_and_transaction) {
   CheckedAutoLock auto_lock(lock_);
-  DCHECK(!replacement_pool_);
+  DCHECK(!replacement_thread_group_);
   priority_queue_.Push(std::move(task_source_and_transaction.task_source),
                        task_source_and_transaction.transaction.GetSortKey());
   EnsureEnoughWorkersLockRequired(executor);
 }
 
-void ThreadGroup::InvalidateAndHandoffAllTaskSourcesToOtherPool(
-    ThreadGroup* destination_pool) {
-  CheckedAutoLock current_pool_lock(lock_);
-  CheckedAutoLock destination_pool_lock(destination_pool->lock_);
-  destination_pool->priority_queue_ = std::move(priority_queue_);
-  replacement_pool_ = destination_pool;
+void ThreadGroup::InvalidateAndHandoffAllTaskSourcesToOtherThreadGroup(
+    ThreadGroup* destination_thread_group) {
+  CheckedAutoLock current_thread_group_lock(lock_);
+  CheckedAutoLock destination_thread_group_lock(
+      destination_thread_group->lock_);
+  destination_thread_group->priority_queue_ = std::move(priority_queue_);
+  replacement_thread_group_ = destination_thread_group;
 }
 
 }  // namespace internal
diff --git a/base/task/thread_pool/thread_group.h b/base/task/thread_pool/thread_group.h
index aba2af2..f0d0508 100644
--- a/base/task/thread_pool/thread_group.h
+++ b/base/task/thread_pool/thread_group.h
@@ -20,7 +20,9 @@
 
 class TaskTracker;
 
-// Interface and base implementation for a worker pool.
+// Interface and base implementation for a thread group. A thread group is a
+// subset of the threads in the thread pool (see GetThreadGroupForTraits() for
+// thread group selection logic when posting tasks and creating task runners).
 class BASE_EXPORT ThreadGroup {
  public:
   // Delegate interface for ThreadGroup.
@@ -29,8 +31,8 @@
     virtual ~Delegate() = default;
 
     // Invoked when the TaskSource in |task_source_and_transaction| is non-empty
-    // after the ThreadGroup has run a task from it. The implementation
-    // must return the pool in which the TaskSource should be reenqueued.
+    // after the ThreadGroup has run a task from it. The implementation must
+    // return the thread group in which the TaskSource should be reenqueued.
     virtual ThreadGroup* GetThreadGroupForTraits(const TaskTraits& traits) = 0;
   };
 
@@ -52,13 +54,13 @@
   void PostTaskWithSequenceNow(Task task,
                                SequenceAndTransaction sequence_and_transaction);
 
-  // Registers the worker pool in TLS.
+  // Registers the thread group in TLS.
   void BindToCurrentThread();
 
-  // Resets the worker pool in TLS.
+  // Resets the thread group in TLS.
   void UnbindFromCurrentThread();
 
-  // Returns true if the worker pool is registered in TLS.
+  // Returns true if the thread group is registered in TLS.
   bool IsBoundToCurrentThread() const;
 
   // Removes |task_source| from |priority_queue_|. Returns true if successful,
@@ -67,29 +69,30 @@
   bool RemoveTaskSource(scoped_refptr<TaskSource> task_source);
 
   // Updates the position of the TaskSource in |task_source_and_transaction| in
-  // this pool's PriorityQueue based on the TaskSource's current traits.
+  // this ThreadGroup's PriorityQueue based on the TaskSource's current traits.
   //
   // Implementations should instantiate a concrete ScopedWorkersExecutor and
   // invoke UpdateSortKeyImpl().
   virtual void UpdateSortKey(
       TaskSourceAndTransaction task_source_and_transaction) = 0;
 
-  // Pushes the TaskSource in |task_source_and_transaction| into this pool's
-  // PriorityQueue and wakes up workers as appropriate.
+  // Pushes the TaskSource in |task_source_and_transaction| into this
+  // ThreadGroup's PriorityQueue and wakes up workers as appropriate.
   //
   // Implementations should instantiate a concrete ScopedWorkersExecutor and
   // invoke PushTaskSourceAndWakeUpWorkersImpl().
   virtual void PushTaskSourceAndWakeUpWorkers(
       TaskSourceAndTransaction task_source_and_transaction) = 0;
 
-  // Removes all task sources from this pool's PriorityQueue and enqueues them
-  // in another |destination_pool|. After this method is called, any task
-  // sources posted to this pool will be forwarded to |destination_pool|.
+  // Removes all task sources from this ThreadGroup's PriorityQueue and enqueues
+  // them in another |destination_thread_group|. After this method is called,
+  // any task sources posted to this ThreadGroup will be forwarded to
+  // |destination_thread_group|.
   //
   // TODO(crbug.com/756547): Remove this method once the UseNativeThreadPool
   // experiment is complete.
-  void InvalidateAndHandoffAllTaskSourcesToOtherPool(
-      ThreadGroup* destination_pool);
+  void InvalidateAndHandoffAllTaskSourcesToOtherThreadGroup(
+      ThreadGroup* destination_thread_group);
 
   // Prevents new tasks from starting to run and waits for currently running
   // tasks to complete their execution. It is guaranteed that no thread will do
@@ -100,7 +103,7 @@
   virtual void JoinForTesting() = 0;
 
   // Returns the maximum number of non-blocked tasks that can run concurrently
-  // in this pool.
+  // in this ThreadGroup.
   //
   // TODO(fdoray): Remove this method. https://crbug.com/687264
   virtual size_t GetMaxConcurrentNonBlockedTasksDeprecated() const = 0;
@@ -123,35 +126,38 @@
     DISALLOW_COPY_AND_ASSIGN(BaseScopedWorkersExecutor);
   };
 
-  // Allows a task source to be pushed to a pool's PriorityQueue at the end of a
-  // scope, when all locks have been released.
+  // Allows a task source to be pushed to a ThreadGroup's PriorityQueue at the
+  // end of a scope, when all locks have been released.
   class ScopedReenqueueExecutor {
    public:
     ScopedReenqueueExecutor();
     ~ScopedReenqueueExecutor();
 
+    // A TaskSourceAndTransaction and the ThreadGroup in which it should be
+    // enqueued.
     void SchedulePushTaskSourceAndWakeUpWorkers(
         TaskSourceAndTransaction task_source_and_transaction,
-        ThreadGroup* destination_pool);
+        ThreadGroup* destination_thread_group);
 
    private:
-    // A TaskSourceAndTransaction and the pool in which it should be enqueued.
+    // A TaskSourceAndTransaction and the thread group in which it should be
+    // enqueued.
     Optional<TaskSourceAndTransaction> task_source_and_transaction_;
-    ThreadGroup* destination_pool_ = nullptr;
+    ThreadGroup* destination_thread_group_ = nullptr;
 
     DISALLOW_COPY_AND_ASSIGN(ScopedReenqueueExecutor);
   };
 
-  // |predecessor_pool| is a pool whose lock can be acquired before the
-  // constructed pool's lock. This is necessary to move all task sources from
-  // |predecessor_pool| to the constructed pool and support the
-  // UseNativeThreadPool experiment.
+  // |predecessor_thread_group| is a ThreadGroup whose lock can be acquired
+  // before the constructed ThreadGroup's lock. This is necessary to move all
+  // task sources from |predecessor_thread_group| to the constructed ThreadGroup
+  // and support the UseNativeThreadPool experiment.
   //
-  // TODO(crbug.com/756547): Remove |predecessor_pool| once the experiment is
-  // complete.
+  // TODO(crbug.com/756547): Remove |predecessor_thread_group| once the
+  // experiment is complete.
   ThreadGroup(TrackedRef<TaskTracker> task_tracker,
               TrackedRef<Delegate> delegate,
-              ThreadGroup* predecessor_pool = nullptr);
+              ThreadGroup* predecessor_thread_group = nullptr);
 
   const TrackedRef<TaskTracker> task_tracker_;
   const TrackedRef<Delegate> delegate_;
@@ -173,7 +179,7 @@
       BaseScopedWorkersExecutor* executor) EXCLUSIVE_LOCKS_REQUIRED(lock_) = 0;
 
   // Reenqueues a |task_source_and_transaction| from which a Task just ran in
-  // the current pool into the appropriate pool.
+  // the current ThreadGroup into the appropriate ThreadGroup.
   void ReEnqueueTaskSourceLockRequired(
       BaseScopedWorkersExecutor* workers_executor,
       ScopedReenqueueExecutor* reenqueue_executor,
@@ -193,13 +199,13 @@
   // within its scope (no thread creation or wake up).
   mutable CheckedLock lock_;
 
-  // PriorityQueue from which all threads of this worker pool get work.
+  // PriorityQueue from which all threads of this ThreadGroup get work.
   PriorityQueue priority_queue_ GUARDED_BY(lock_);
 
-  // If |replacement_pool_| is non-null, this pool is invalid and all task
-  // sources should be scheduled on |replacement_pool_|. Used to support the
-  // UseNativeThreadPool experiment.
-  ThreadGroup* replacement_pool_ = nullptr;
+  // If |replacement_thread_group_| is non-null, this ThreadGroup is invalid and
+  // all task sources should be scheduled on |replacement_thread_group_|. Used
+  // to support the UseNativeThreadPool experiment.
+  ThreadGroup* replacement_thread_group_ = nullptr;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ThreadGroup);
diff --git a/base/task/thread_pool/thread_group_impl.cc b/base/task/thread_pool/thread_group_impl.cc
index a18cbfc..4912b4e1 100644
--- a/base/task/thread_pool/thread_group_impl.cc
+++ b/base/task/thread_pool/thread_group_impl.cc
@@ -55,8 +55,8 @@
     "ThreadPool.NumActiveWorkers.";
 constexpr size_t kMaxNumberOfWorkers = 256;
 
-// In a background pool:
-// - Blocking calls take more time than in a foreground pool.
+// In a background thread group:
+// - Blocking calls take more time than in a foreground thread group.
 // - We want to minimize impact on foreground work, not maximize execution
 //   throughput.
 // For these reasons, the timeout to increase the maximum number of concurrent
@@ -64,7 +64,7 @@
 // infinite because execution throughput should not be reduced forever if a task
 // blocks forever.
 //
-// TODO(fdoray): On platforms without background pools, blocking in a
+// TODO(fdoray): On platforms without background thread groups, blocking in a
 // BEST_EFFORT task should:
 // 1. Increment the maximum number of concurrent tasks after a *short* timeout,
 //    to allow scheduling of USER_VISIBLE/USER_BLOCKING tasks.
@@ -72,7 +72,7 @@
 //    *long* timeout, because we only want to allow more BEST_EFFORT tasks to be
 //    be scheduled concurrently when we believe that a BEST_EFFORT task is
 //    blocked forever.
-// Currently, only 1. is true as the configuration is per pool.
+// Currently, only 1. is true as the configuration is per thread group.
 // TODO(https://crbug.com/927755): Fix racy condition when MayBlockThreshold ==
 // BlockedWorkersPoll.
 constexpr TimeDelta kForegroundMayBlockThreshold =
@@ -246,11 +246,11 @@
 
  private:
   // Returns true if |worker| is allowed to cleanup and remove itself from the
-  // pool. Called from GetWork() when no work is available.
+  // thread group. Called from GetWork() when no work is available.
   bool CanCleanupLockRequired(const WorkerThread* worker) const
       EXCLUSIVE_LOCKS_REQUIRED(outer_->lock_);
 
-  // Calls cleanup on |worker| and removes it from the pool. Called from
+  // Calls cleanup on |worker| and removes it from the thread group. Called from
   // GetWork() when no work is available and CanCleanupLockRequired() returns
   // true.
   void CleanupLockRequired(WorkerThread* worker)
@@ -324,12 +324,12 @@
 };
 
 ThreadGroupImpl::ThreadGroupImpl(StringPiece histogram_label,
-                                 StringPiece pool_label,
+                                 StringPiece thread_group_label,
                                  ThreadPriority priority_hint,
                                  TrackedRef<TaskTracker> task_tracker,
                                  TrackedRef<Delegate> delegate)
     : ThreadGroup(std::move(task_tracker), std::move(delegate)),
-      pool_label_(pool_label.as_string()),
+      thread_group_label_(thread_group_label.as_string()),
       priority_hint_(priority_hint),
       idle_workers_stack_cv_for_testing_(lock_.CreateConditionVariable()),
       // Mimics the UMA_HISTOGRAM_LONG_TIMES macro.
@@ -378,7 +378,7 @@
           HistogramBase::kUmaTargetedHistogramFlag)),
       tracked_ref_factory_(this) {
   DCHECK(!histogram_label.empty());
-  DCHECK(!pool_label_.empty());
+  DCHECK(!thread_group_label_.empty());
 }
 
 void ThreadGroupImpl::Start(
@@ -388,7 +388,7 @@
     WorkerThreadObserver* worker_thread_observer,
     WorkerEnvironment worker_environment,
     Optional<TimeDelta> may_block_threshold) {
-  DCHECK(!replacement_pool_);
+  DCHECK(!replacement_thread_group_);
 
   ScopedWorkersExecutor executor(this);
 
@@ -451,7 +451,7 @@
   CheckedAutoLock auto_lock(lock_);
   DCHECK_NE(after_start().initial_max_tasks, 0U)
       << "GetMaxConcurrentTasksDeprecated() should only be called after the "
-      << "worker pool has started.";
+      << "thread group has started.";
 #endif
   return after_start().initial_max_tasks;
 }
@@ -496,7 +496,8 @@
     CheckedAutoLock auto_lock(lock_);
     priority_queue_.EnableFlushTaskSourcesOnDestroyForTesting();
 
-    DCHECK_GT(workers_.size(), size_t(0)) << "Joined an unstarted worker pool.";
+    DCHECK_GT(workers_.size(), size_t(0))
+        << "Joined an unstarted thread group.";
 
     // Ensure WorkerThreads in |workers_| do not attempt to cleanup while
     // being joined.
@@ -584,7 +585,7 @@
   DCHECK_EQ(worker_only().num_tasks_since_last_wait, 0U);
 
   PlatformThread::SetName(
-      StringPrintf("ThreadPool%sWorker", outer_->pool_label_.c_str()));
+      StringPrintf("ThreadPool%sWorker", outer_->thread_group_label_.c_str()));
 
   outer_->BindToCurrentThread();
   SetBlockingObserverForCurrentThread(this);
@@ -790,8 +791,8 @@
 
     // |worker| should already have been removed from the idle workers stack and
     // |workers_| by the time the thread is about to exit. (except in the cases
-    // where the pool is no longer going to be used - in which case, it's fine
-    // for there to be invalid workers in the pool.
+    // where the thread group is no longer going to be used - in which case,
+    // it's fine for there to be invalid workers in the thread group.
     if (!shutdown_complete && !outer_->join_for_testing_started_.IsSet()) {
       DCHECK(!outer_->idle_workers_stack_.Contains(worker));
       DCHECK(!ContainsWorker(outer_->workers_, worker));
@@ -923,7 +924,8 @@
 
   // Excess workers should not get work, until they are no longer excess (i.e.
   // max tasks increases). This ensures that if we have excess workers in the
-  // pool, they get a chance to no longer be excess before being cleaned up.
+  // thread group, they get a chance to no longer be excess before being cleaned
+  // up.
   if (outer_->GetNumAwakeWorkersLockRequired() >
       outer_->GetDesiredNumAwakeWorkersLockRequired()) {
     OnWorkerBecomesIdleLockRequired(worker);
@@ -1046,7 +1048,7 @@
 
 void ThreadGroupImpl::EnsureEnoughWorkersLockRequired(
     BaseScopedWorkersExecutor* base_executor) {
-  // Don't do anything if the pool isn't started.
+  // Don't do anything if the thread group isn't started.
   if (max_tasks_ == 0)
     return;
 
diff --git a/base/task/thread_pool/thread_group_impl.h b/base/task/thread_pool/thread_group_impl.h
index 418c701..0542525 100644
--- a/base/task/thread_pool/thread_group_impl.h
+++ b/base/task/thread_pool/thread_group_impl.h
@@ -42,37 +42,37 @@
 
 class TaskTracker;
 
-// A pool of workers that run Tasks.
+// A group of workers that run Tasks.
 //
-// The pool doesn't create threads until Start() is called. Tasks can be posted
-// at any time but will not run until after Start() is called.
+// The thread group doesn't create threads until Start() is called. Tasks can be
+// posted at any time but will not run until after Start() is called.
 //
 // This class is thread-safe.
 class BASE_EXPORT ThreadGroupImpl : public ThreadGroup {
  public:
-  // Constructs a pool without workers.
+  // Constructs a group without workers.
   //
-  // |histogram_label| is used to label the pool's histograms ("ThreadPool."
-  // + histogram_name + "." + |histogram_label| + extra suffixes), it must not
-  // be empty. |pool_label| is used to label the pool's threads, it must not be
-  // empty. |priority_hint| is the preferred thread priority; the actual thread
-  // priority depends on shutdown state and platform capabilities.
-  // |task_tracker| keeps track of tasks.
+  // |histogram_label| is used to label the thread group's histograms as
+  // "ThreadPool." + histogram_name + "." + |histogram_label| + extra suffixes.
+  // It must not be empty. |thread group_label| is used to label the thread
+  // group's threads, it must not be empty. |priority_hint| is the preferred
+  // thread priority; the actual thread priority depends on shutdown state and
+  // platform capabilities. |task_tracker| keeps track of tasks.
   ThreadGroupImpl(StringPiece histogram_label,
-                  StringPiece pool_label,
+                  StringPiece thread_group_label,
                   ThreadPriority priority_hint,
                   TrackedRef<TaskTracker> task_tracker,
                   TrackedRef<Delegate> delegate);
 
   // Creates workers following the |params| specification, allowing existing and
-  // future tasks to run. The pool runs at most |max_best_effort_tasks|
+  // future tasks to run. The thread group runs at most |max_best_effort_tasks|
   // unblocked BEST_EFFORT tasks concurrently, uses |service_thread_task_runner|
   // to monitor for blocked tasks, and, if specified, notifies
-  // |worker_thread_observer| when a worker enters and exits its main
-  // function (the observer must not be destroyed before JoinForTesting() has
-  // returned). |worker_environment| specifies the environment in which tasks
-  // are executed. |may_block_threshold| is the timeout after which a task in a
-  // MAY_BLOCK ScopedBlockingCall is considered blocked (the pool will choose an
+  // |worker_thread_observer| when a worker enters and exits its main function
+  // (the observer must not be destroyed before JoinForTesting() has returned).
+  // |worker_environment| specifies the environment in which tasks are executed.
+  // |may_block_threshold| is the timeout after which a task in a MAY_BLOCK
+  // ScopedBlockingCall is considered blocked (the thread group will choose an
   // appropriate value if none is specified). Can only be called once. CHECKs on
   // failure.
   void Start(const ThreadGroupParams& params,
@@ -124,7 +124,7 @@
   // WaitForWorkersCleanedUpForTesting() or Start() if it wasn't called yet).
   void WaitForWorkersCleanedUpForTesting(size_t n);
 
-  // Returns the number of workers in this worker pool.
+  // Returns the number of workers in this thread group.
   size_t NumberOfWorkersForTesting() const;
 
   // Returns |max_tasks_|.
@@ -160,8 +160,8 @@
   // Returns true if worker cleanup is permitted.
   bool CanWorkerCleanupForTestingLockRequired() EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
-  // Creates a worker, adds it to the pool, schedules its start and returns it.
-  // Cannot be called before Start().
+  // Creates a worker, adds it to the thread group, schedules its start and
+  // returns it. Cannot be called before Start().
   scoped_refptr<WorkerThread> CreateAndRegisterWorkerLockRequired(
       ScopedWorkersExecutor* executor) EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
@@ -184,8 +184,8 @@
     return after_start().may_block_threshold;
   }
 
-  // Interval at which the service thread checks for workers in this pool
-  // that have been in a MAY_BLOCK ScopedBlockingCall for more than
+  // Interval at which the service thread checks for workers in this thread
+  // group that have been in a MAY_BLOCK ScopedBlockingCall for more than
   // may_block_threshold().
   TimeDelta blocked_workers_poll_period_for_testing() const {
     return after_start().blocked_workers_poll_period;
@@ -204,9 +204,9 @@
   bool ShouldPeriodicallyAdjustMaxTasksLockRequired()
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
-  // Increments/decrements the number of tasks that can run in this pool.
-  // |is_running_best_effort_task| indicates whether the worker causing the
-  // change is currently running a TaskPriority::BEST_EFFORT task.
+  // Increments/decrements the number of tasks that can run in this thread
+  // group. |is_running_best_effort_task| indicates whether the worker causing
+  // the change is currently running a TaskPriority::BEST_EFFORT task.
   void DecrementMaxTasksLockRequired(bool is_running_best_effort_task)
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
   void IncrementMaxTasksLockRequired(bool is_running_best_effort_task)
@@ -244,7 +244,7 @@
     // worker that is within a MAY_BLOCK ScopedBlockingCall.
     TimeDelta may_block_threshold;
 
-    // The period between calls to AdjustMaxTasks() when the pool is at
+    // The period between calls to AdjustMaxTasks() when the thread group is at
     // capacity.
     TimeDelta blocked_workers_poll_period;
   } initialized_in_start_;
@@ -262,19 +262,19 @@
     return initialized_in_start_;
   }
 
-  const std::string pool_label_;
+  const std::string thread_group_label_;
   const ThreadPriority priority_hint_;
 
-  // All workers owned by this worker pool.
+  // All workers owned by this thread group.
   std::vector<scoped_refptr<WorkerThread>> workers_ GUARDED_BY(lock_);
 
   // Maximum number of tasks of any priority / BEST_EFFORT priority that can run
-  // concurrently in this pool.
+  // concurrently in this thread group.
   size_t max_tasks_ GUARDED_BY(lock_) = 0;
   size_t max_best_effort_tasks_ GUARDED_BY(lock_) = 0;
 
   // Number of tasks of any priority / BEST_EFFORT priority that are currently
-  // running in this pool.
+  // running in this thread group.
   size_t num_running_tasks_ GUARDED_BY(lock_) = 0;
   size_t num_running_best_effort_tasks_ GUARDED_BY(lock_) = 0;
 
@@ -327,23 +327,23 @@
   AtomicFlag join_for_testing_started_;
 #endif
 
-  // ThreadPool.DetachDuration.[worker pool name] histogram. Intentionally
+  // ThreadPool.DetachDuration.[thread group name] histogram. Intentionally
   // leaked.
   HistogramBase* const detach_duration_histogram_;
 
-  // ThreadPool.NumTasksBeforeDetach.[worker pool name] histogram.
+  // ThreadPool.NumTasksBeforeDetach.[thread group name] histogram.
   // Intentionally leaked.
   HistogramBase* const num_tasks_before_detach_histogram_;
 
-  // ThreadPool.NumTasksBetweenWaits.[worker pool name] histogram.
+  // ThreadPool.NumTasksBetweenWaits.[thread group name] histogram.
   // Intentionally leaked.
   HistogramBase* const num_tasks_between_waits_histogram_;
 
-  // ThreadPool.NumWorkers.[worker pool name] histogram.
+  // ThreadPool.NumWorkers.[thread group name] histogram.
   // Intentionally leaked.
   HistogramBase* const num_workers_histogram_;
 
-  // ThreadPool.NumActiveWorkers.[worker pool name] histogram.
+  // ThreadPool.NumActiveWorkers.[thread group name] histogram.
   // Intentionally leaked.
   HistogramBase* const num_active_workers_histogram_;
 
diff --git a/base/task/thread_pool/thread_group_impl_unittest.cc b/base/task/thread_pool/thread_group_impl_unittest.cc
index 2f09337..35b05a38 100644
--- a/base/task/thread_pool/thread_group_impl_unittest.cc
+++ b/base/task/thread_pool/thread_group_impl_unittest.cc
@@ -303,7 +303,7 @@
  public:
   void SetUp() override {
     CreateThreadGroup();
-    // Let the test start the worker pool.
+    // Let the test start the thread group.
   }
 };
 
@@ -344,15 +344,15 @@
           BindOnce(&TaskPostedBeforeStart, Unretained(&task_2_thread_ref),
                    Unretained(&task_2_running), Unretained(&barrier)));
 
-  // Workers should not be created and tasks should not run before the pool is
-  // started.
+  // Workers should not be created and tasks should not run before the thread
+  // group is started.
   EXPECT_EQ(0U, thread_group_->NumberOfWorkersForTesting());
   EXPECT_FALSE(task_1_running.IsSignaled());
   EXPECT_FALSE(task_2_running.IsSignaled());
 
   StartThreadGroup(TimeDelta::Max(), kMaxTasks);
 
-  // Tasks should run shortly after the pool is started.
+  // Tasks should run shortly after the thread group is started.
   task_1_running.Wait();
   task_2_running.Wait();
 
@@ -463,7 +463,7 @@
   // All workers should be done running by now, so reset for the next phase.
   waiter_.Reset();
 
-  // Wait for the worker pool to clean up at least one worker.
+  // Wait for the thread group to clean up at least one worker.
   thread_group_->WaitForWorkersCleanedUpForTesting(1U);
 
   // Saturate and count the worker threads that do not have the magic TLS value.
@@ -495,15 +495,15 @@
   ThreadGroupImplHistogramTest() = default;
 
  protected:
-  // Override SetUp() to allow every test case to initialize a worker pool with
+  // Override SetUp() to allow every test case to initialize a thread group with
   // its own arguments.
   void SetUp() override {}
 
   // Floods |thread_group_| with a single task each that blocks until
-  // |continue_event| is signaled. Every worker in the pool is blocked on
-  // |continue_event| when this method returns. Note: this helper can easily be
-  // generalized to be useful in other tests, but it's here for now because it's
-  // only used in a ThreadGroupImplHistogramTest at the moment.
+  // |continue_event| is signaled. Every worker in the thread group is blocked
+  // on |continue_event| when this method returns. Note: this helper can easily
+  // be generalized to be useful in other tests, but it's here for now because
+  // it's only used in a ThreadGroupImplHistogramTest at the moment.
   void FloodPool(WaitableEvent* continue_event) {
     ASSERT_FALSE(continue_event->IsSignaled());
 
@@ -608,7 +608,7 @@
             histogram->SnapshotSamples()->GetCount(1));
   EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10));
 
-  // Flooding the pool once again (without letting any workers go idle)
+  // Flooding the thread group once again (without letting any workers go idle)
   // shouldn't affect the counts either.
 
   workers_continue.Reset();
@@ -664,17 +664,17 @@
           Unretained(&thread_ref), Unretained(&cleanup_thread_running),
           Unretained(&cleanup_thread_continue)));
 
-  // Start the worker pool with 2 workers, to avoid depending on the scheduler's
+  // Start the thread group with 2 workers, to avoid depending on the internal
   // logic to always keep one extra idle worker.
   //
-  // The pool is started after the 3 initial tasks have been posted to ensure
-  // that they are scheduled on the same worker. If the tasks could run as they
-  // are posted, there would be a chance that:
+  // The thread group is started after the 3 initial tasks have been posted to
+  // ensure that they are scheduled on the same worker. If the tasks could run
+  // as they are posted, there would be a chance that:
   // 1. Worker #1:        Runs a tasks and empties the sequence, without adding
   //                      itself to the idle stack yet.
-  // 2. Posting thread:   Posts another task to the now empty sequence. Wakes
-  //                      up a new worker, since worker #1 isn't on the idle
-  //                      stack yet.
+  // 2. Posting thread:   Posts another task to the now empty sequence.
+  //                      Wakes up a new worker, since worker #1 isn't on the
+  //                      idle stack yet.
   // 3: Worker #2:        Runs the tasks, violating the expectation that the 3
   //                      initial tasks run on the same worker.
   constexpr size_t kTwoWorkers = 2;
@@ -782,8 +782,8 @@
   // Wait long enough for all but one worker to clean up.
   thread_group_->WaitForWorkersCleanedUpForTesting(kMaxTasks - 1);
   EXPECT_EQ(1U, thread_group_->NumberOfWorkersForTesting());
-  // Give extra time for a worker to cleanup : none should as the pool is
-  // expected to keep a worker ready regardless of how long it was idle for.
+  // Give extra time for a worker to cleanup : none should as the thread group
+  // is expected to keep a worker ready regardless of how long it was idle for.
   PlatformThread::Sleep(kReclaimTimeForCleanupTests);
   EXPECT_EQ(1U, thread_group_->NumberOfWorkersForTesting());
 }
@@ -844,7 +844,7 @@
   PlatformThread::Sleep(kReclaimTimeForCleanupTests * 2);
   EXPECT_EQ(2U, thread_group_->NumberOfWorkersForTesting());
 
-  // Then also flood the pool (cycling the top of the idle stack).
+  // Then also flood the thread group (cycling the top of the idle stack).
   {
     auto task_runner = test::CreateTaskRunnerWithTraits(
         {WithBaseSyncPrimitives()}, &mock_pooled_task_runner_delegate_);
@@ -949,7 +949,7 @@
   void TearDown() override { ThreadGroupImplImplTestBase::CommonTearDown(); }
 
  protected:
-  // Saturates the worker pool with a task that first blocks, waits to be
+  // Saturates the thread group with a task that first blocks, waits to be
   // unblocked, then exits.
   void SaturateWithBlockingTasks(
       const NestedBlockingType& nested_blocking_type) {
@@ -972,7 +972,7 @@
     threads_running.Wait();
   }
 
-  // Saturates the worker pool with a task that waits for other tasks without
+  // Saturates the thread group with a task that waits for other tasks without
   // entering a ScopedBlockingCall, then exits.
   void SaturateWithBusyTasks() {
     WaitableEvent threads_running;
@@ -1050,7 +1050,7 @@
   EXPECT_EQ(thread_group_->GetMaxTasksForTesting(), kMaxTasks);
 }
 
-// Verify that flooding the pool with more BEST_EFFORT tasks than
+// Verify that flooding the thread group with more BEST_EFFORT tasks than
 // kMaxBestEffortTasks doesn't prevent USER_VISIBLE tasks from running.
 TEST_P(ThreadGroupImplBlockingTest, TooManyBestEffortTasks) {
   constexpr size_t kMaxBestEffortTasks = kMaxTasks / 2;
@@ -1117,8 +1117,8 @@
   task_tracker_.FlushForTesting();
 }
 
-// Verify that tasks posted in a saturated pool before a ScopedBlockingCall will
-// execute after ScopedBlockingCall is instantiated.
+// Verify that tasks posted in a saturated thread group before a
+// ScopedBlockingCall will execute after ScopedBlockingCall is instantiated.
 TEST_P(ThreadGroupImplBlockingTest, PostBeforeBlocking) {
   CreateAndStartThreadGroup();
 
@@ -1145,8 +1145,8 @@
     thread_running.Wait();
   }
 
-  // All workers should be occupied and the pool should be saturated. Workers
-  // have not entered ScopedBlockingCall yet.
+  // All workers should be occupied and the thread group should be saturated.
+  // Workers have not entered ScopedBlockingCall yet.
   EXPECT_EQ(thread_group_->NumberOfWorkersForTesting(), kMaxTasks);
   EXPECT_EQ(thread_group_->GetMaxTasksForTesting(), kMaxTasks);
 
@@ -1181,8 +1181,8 @@
   task_tracker_.FlushForTesting();
 }
 
-// Verify that workers become idle when the pool is over-capacity and that
-// those workers do no work.
+// Verify that workers become idle when the thread group is over-capacity and
+// that those workers do no work.
 TEST_P(ThreadGroupImplBlockingTest, WorkersIdleWhenOverCapacity) {
   CreateAndStartThreadGroup();
 
@@ -1207,15 +1207,15 @@
                                           Unretained(&is_exiting)));
   }
 
-  // The original |kMaxTasks| will finish their tasks after being
-  // unblocked. There will be work in the work queue, but the pool should now
-  // be over-capacity and workers will become idle.
+  // The original |kMaxTasks| will finish their tasks after being unblocked.
+  // There will be work in the work queue, but the thread group should now be
+  // over-capacity and workers will become idle.
   UnblockBlockingTasks();
   thread_group_->WaitForWorkersIdleForTesting(kMaxTasks);
   EXPECT_EQ(thread_group_->NumberOfIdleWorkersForTesting(), kMaxTasks);
 
-  // Posting more tasks should not cause workers idle from the pool being over
-  // capacity to begin doing work.
+  // Posting more tasks should not cause workers idle from the thread group
+  // being over capacity to begin doing work.
   for (size_t i = 0; i < kMaxTasks; ++i) {
     task_runner_->PostTask(FROM_HERE, BindOnce(
                                           [](AtomicFlag* is_exiting) {
@@ -1255,8 +1255,8 @@
 // but exits the scope before the MayBlock threshold is reached, that the max
 // tasks does not increase.
 TEST_F(ThreadGroupImplBlockingTest, ThreadBlockUnblockPremature) {
-  // Create a pool with an infinite MayBlock threshold so that a MAY_BLOCK
-  // ScopedBlockingCall never increases the max tasks.
+  // Create a thread group with an infinite MayBlock threshold so that a
+  // MAY_BLOCK ScopedBlockingCall never increases the max tasks.
   CreateAndStartThreadGroup(TimeDelta::Max(),  // |suggested_reclaim_time|
                             kMaxTasks,         // |max_tasks|
                             nullopt,           // |max_best_effort_tasks|
@@ -1290,8 +1290,8 @@
                                        &mock_pooled_task_runner_delegate_);
   WaitableEvent can_return;
 
-  // Saturate the pool so that a MAY_BLOCK ScopedBlockingCall would increment
-  // the max tasks.
+  // Saturate the thread group so that a MAY_BLOCK ScopedBlockingCall would
+  // increment the max tasks.
   for (size_t i = 0; i < kMaxTasks - 1; ++i) {
     task_runner->PostTask(
         FROM_HERE,
@@ -1364,8 +1364,8 @@
   DISALLOW_COPY_AND_ASSIGN(ThreadGroupImplOverCapacityTest);
 };
 
-// Verify that workers that become idle due to the pool being over capacity will
-// eventually cleanup.
+// Verify that workers that become idle due to the thread group being over
+// capacity will eventually cleanup.
 TEST_F(ThreadGroupImplOverCapacityTest, VerifyCleanup) {
   WaitableEvent threads_running;
   WaitableEvent threads_continue;
@@ -1420,7 +1420,8 @@
   extra_threads_continue.Signal();
 
   // Periodically post tasks to ensure that posting tasks does not prevent
-  // workers that are idle due to the pool being over capacity from cleaning up.
+  // workers that are idle due to the thread group being over capacity from
+  // cleaning up.
   for (int i = 0; i < 16; ++i) {
     task_runner_->PostDelayedTask(FROM_HERE, DoNothing(),
                                   kReclaimTimeForCleanupTests * i * 0.5);
@@ -1436,7 +1437,7 @@
 }
 
 // Verify that the maximum number of workers is 256 and that hitting the max
-// leaves the pool in a valid state with regards to max tasks.
+// leaves the thread group in a valid state with regards to max tasks.
 TEST_F(ThreadGroupImplBlockingTest, MaximumWorkersTest) {
   CreateAndStartThreadGroup();
 
@@ -1489,8 +1490,8 @@
                                Unretained(&late_blocking_threads_running)));
 
   // Posts additional tasks. Note: we should already have |kMaxNumberOfWorkers|
-  // tasks running. These tasks should not be able to get executed yet as
-  // the pool is already at its max worker cap.
+  // tasks running. These tasks should not be able to get executed yet as the
+  // thread group is already at its max worker cap.
   for (size_t i = 0; i < kNumExtraTasks; ++i) {
     task_runner_->PostTask(
         FROM_HERE,
@@ -1520,7 +1521,7 @@
       kMaxTasks,
       BindOnce(&WaitableEvent::Signal, Unretained(&final_tasks_running)));
 
-  // Verify that we are still able to saturate the pool.
+  // Verify that we are still able to saturate the thread group.
   for (size_t i = 0; i < kMaxTasks; ++i) {
     task_runner_->PostTask(
         FROM_HERE,
@@ -1596,8 +1597,8 @@
   task_tracker_.FlushForTesting();
 }
 
-// Verify that flooding the pool with BEST_EFFORT tasks doesn't cause the
-// creation of more than |max_best_effort_tasks| + 1 workers.
+// Verify that flooding the thread group with BEST_EFFORT tasks doesn't cause
+// the creation of more than |max_best_effort_tasks| + 1 workers.
 TEST_F(ThreadGroupImplImplStartInBodyTest,
        FloodBestEffortTasksDoesNotCreateTooManyWorkers) {
   constexpr size_t kMaxBestEffortTasks = kMaxTasks / 2;
@@ -1695,7 +1696,7 @@
                    }));
   hold_will_block_task.Signal();
 
-  // Join the pool to avoid invalid accesses to |worker_observer|.
+  // Join the thread group to avoid invalid accesses to |worker_observer|.
   task_tracker_.FlushForTesting();
   thread_group_->JoinForTesting();
   thread_group_.reset();
diff --git a/base/task/thread_pool/thread_group_native.cc b/base/task/thread_pool/thread_group_native.cc
index 0f0403b..d40cbd0 100644
--- a/base/task/thread_pool/thread_group_native.cc
+++ b/base/task/thread_pool/thread_group_native.cc
@@ -39,10 +39,10 @@
 
 ThreadGroupNative::ThreadGroupNative(TrackedRef<TaskTracker> task_tracker,
                                      TrackedRef<Delegate> delegate,
-                                     ThreadGroup* predecessor_pool)
+                                     ThreadGroup* predecessor_thread_group)
     : ThreadGroup(std::move(task_tracker),
                   std::move(delegate),
-                  predecessor_pool) {}
+                  predecessor_thread_group) {}
 
 ThreadGroupNative::~ThreadGroupNative() {
 #if DCHECK_IS_ON()
diff --git a/base/task/thread_pool/thread_group_native.h b/base/task/thread_pool/thread_group_native.h
index a2a4f26..c579227 100644
--- a/base/task/thread_pool/thread_group_native.h
+++ b/base/task/thread_pool/thread_group_native.h
@@ -19,7 +19,7 @@
   // JoinForTesting() has returned.
   ~ThreadGroupNative() override;
 
-  // Starts the worker pool and allows tasks to begin running.
+  // Starts the thread group and allows tasks to begin running.
   void Start(WorkerEnvironment worker_environment = WorkerEnvironment::NONE);
 
   // ThreadGroup:
@@ -31,7 +31,7 @@
  protected:
   ThreadGroupNative(TrackedRef<TaskTracker> task_tracker,
                     TrackedRef<Delegate> delegate,
-                    ThreadGroup* predecessor_pool);
+                    ThreadGroup* predecessor_thread_group);
 
   // Runs a task off the next task source on the |priority_queue_|. Called by
   // callbacks posted to platform native thread pools.
@@ -59,11 +59,11 @@
   // if the |priority_queue_| is empty.
   scoped_refptr<TaskSource> GetWork();
 
-  // Indicates whether the pool has been started yet.
+  // Indicates whether the thread group has been started yet.
   bool started_ GUARDED_BY(lock_) = false;
 
-  // Number of threadpool work submitted to the pool which haven't popped a
-  // TaskSource from the PriorityQueue yet.
+  // Number of threadpool work submitted to the thread group which haven't
+  // popped a TaskSource from the PriorityQueue yet.
   size_t num_pending_threadpool_work_ GUARDED_BY(lock_) = 0;
 
 #if DCHECK_IS_ON()
diff --git a/base/task/thread_pool/thread_group_native_mac.h b/base/task/thread_pool/thread_group_native_mac.h
index 74c2e43..f8aa0ee 100644
--- a/base/task/thread_pool/thread_group_native_mac.h
+++ b/base/task/thread_pool/thread_group_native_mac.h
@@ -26,7 +26,7 @@
  public:
   ThreadGroupNativeMac(TrackedRef<TaskTracker> task_tracker,
                        TrackedRef<Delegate> delegate,
-                       ThreadGroup* predecessor_pool = nullptr);
+                       ThreadGroup* predecessor_thread_group = nullptr);
 
   ~ThreadGroupNativeMac() override;
 
diff --git a/base/task/thread_pool/thread_group_native_mac.mm b/base/task/thread_pool/thread_group_native_mac.mm
index 8caf65a..d6f205c 100644
--- a/base/task/thread_pool/thread_group_native_mac.mm
+++ b/base/task/thread_pool/thread_group_native_mac.mm
@@ -9,12 +9,13 @@
 namespace base {
 namespace internal {
 
-ThreadGroupNativeMac::ThreadGroupNativeMac(TrackedRef<TaskTracker> task_tracker,
-                                           TrackedRef<Delegate> delegate,
-                                           ThreadGroup* predecessor_pool)
+ThreadGroupNativeMac::ThreadGroupNativeMac(
+    TrackedRef<TaskTracker> task_tracker,
+    TrackedRef<Delegate> delegate,
+    ThreadGroup* predecessor_thread_group)
     : ThreadGroupNative(std::move(task_tracker),
                         std::move(delegate),
-                        predecessor_pool) {}
+                        predecessor_thread_group) {}
 
 ThreadGroupNativeMac::~ThreadGroupNativeMac() {}
 
diff --git a/base/task/thread_pool/thread_group_native_win.cc b/base/task/thread_pool/thread_group_native_win.cc
index f18611d..317293f1 100644
--- a/base/task/thread_pool/thread_group_native_win.cc
+++ b/base/task/thread_pool/thread_group_native_win.cc
@@ -40,12 +40,13 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedCallbackMayRunLongObserver);
 };
 
-ThreadGroupNativeWin::ThreadGroupNativeWin(TrackedRef<TaskTracker> task_tracker,
-                                           TrackedRef<Delegate> delegate,
-                                           ThreadGroup* predecessor_pool)
+ThreadGroupNativeWin::ThreadGroupNativeWin(
+    TrackedRef<TaskTracker> task_tracker,
+    TrackedRef<Delegate> delegate,
+    ThreadGroup* predecessor_thread_group)
     : ThreadGroupNative(std::move(task_tracker),
                         std::move(delegate),
-                        predecessor_pool) {}
+                        predecessor_thread_group) {}
 
 ThreadGroupNativeWin::~ThreadGroupNativeWin() {
   ::DestroyThreadpoolEnvironment(&environment_);
@@ -77,12 +78,12 @@
 }
 
 // static
-void CALLBACK ThreadGroupNativeWin::RunNextTaskSource(
-    PTP_CALLBACK_INSTANCE callback_instance,
-    void* scheduler_thread_group_windows_impl,
-    PTP_WORK) {
+void CALLBACK
+ThreadGroupNativeWin::RunNextTaskSource(PTP_CALLBACK_INSTANCE callback_instance,
+                                        void* thread_group_windows_impl,
+                                        PTP_WORK) {
   auto* thread_group =
-      static_cast<ThreadGroupNativeWin*>(scheduler_thread_group_windows_impl);
+      static_cast<ThreadGroupNativeWin*>(thread_group_windows_impl);
 
   // Windows Thread Pool API best practices state that all resources created
   // in the callback function should be cleaned up before returning from the
diff --git a/base/task/thread_pool/thread_group_native_win.h b/base/task/thread_pool/thread_group_native_win.h
index 1f1db7b..2df9be1 100644
--- a/base/task/thread_pool/thread_group_native_win.h
+++ b/base/task/thread_pool/thread_group_native_win.h
@@ -28,7 +28,7 @@
  public:
   ThreadGroupNativeWin(TrackedRef<TaskTracker> task_tracker,
                        TrackedRef<Delegate> delegate,
-                       ThreadGroup* predecessor_pool = nullptr);
+                       ThreadGroup* predecessor_thread_group = nullptr);
 
   ~ThreadGroupNativeWin() override;
 
@@ -38,7 +38,7 @@
   // Callback that gets run by |pool_|.
   static void CALLBACK
   RunNextTaskSource(PTP_CALLBACK_INSTANCE callback_instance,
-                    void* scheduler_thread_group_windows_impl,
+                    void* thread_group_windows_impl,
                     PTP_WORK);
 
   // ThreadGroupNative:
diff --git a/base/task/thread_pool/thread_group_params.h b/base/task/thread_pool/thread_group_params.h
index f89408c..8b3df3b0f 100644
--- a/base/task/thread_pool/thread_group_params.h
+++ b/base/task/thread_pool/thread_group_params.h
@@ -12,12 +12,12 @@
 
 class BASE_EXPORT ThreadGroupParams final {
  public:
-  // Constructs a set of params used to initialize a pool. The pool will run
-  // concurrently at most |max_tasks| that aren't blocked (ScopedBlockingCall).
-  // |suggested_reclaim_time| sets a suggestion on when to reclaim idle threads.
-  // The pool is free to ignore this value for performance or correctness
-  // reasons. |backward_compatibility| indicates whether backward compatibility
-  // is enabled.
+  // Constructs a set of params used to initialize a ThreadGroup. The
+  // ThreadGroup will run concurrently at most |max_tasks| that aren't blocked
+  // (ScopedBlockingCall). |suggested_reclaim_time| sets a suggestion on when to
+  // reclaim idle threads. The ThreadGroup is free to ignore this value for
+  // performance or correctness reasons. |backward_compatibility| indicates
+  // whether backward compatibility is enabled.
   ThreadGroupParams(int max_tasks,
                     TimeDelta suggested_reclaim_time,
                     WorkerThreadBackwardCompatibility backward_compatibility =
diff --git a/base/task/thread_pool/thread_group_unittest.cc b/base/task/thread_pool/thread_group_unittest.cc
index 13104b80..189b297 100644
--- a/base/task/thread_pool/thread_group_unittest.cc
+++ b/base/task/thread_pool/thread_group_unittest.cc
@@ -53,7 +53,8 @@
 #endif
 
 constexpr size_t kMaxTasks = 4;
-// By default, tests allow half of the pool to be used by best-effort tasks.
+// By default, tests allow half of the thread group to be used by best-effort
+// tasks.
 constexpr size_t kMaxBestEffortTasks = kMaxTasks / 2;
 constexpr size_t kNumThreadsPostingTasks = 4;
 constexpr size_t kNumTasksPostedPerThread = 150;
@@ -146,18 +147,18 @@
     ASSERT_TRUE(thread_group_);
     switch (GetParam().pool_type) {
       case test::PoolType::GENERIC: {
-        ThreadGroupImpl* scheduler_thread_group_impl =
+        ThreadGroupImpl* thread_group_impl =
             static_cast<ThreadGroupImpl*>(thread_group_.get());
-        scheduler_thread_group_impl->Start(
+        thread_group_impl->Start(
             ThreadGroupParams(kMaxTasks, TimeDelta::Max()), kMaxBestEffortTasks,
             service_thread_.task_runner(), nullptr, worker_environment);
         break;
       }
 #if defined(OS_WIN) || defined(OS_MACOSX)
       case test::PoolType::NATIVE: {
-        ThreadGroupNativeType* scheduler_thread_group_native_impl =
+        ThreadGroupNativeType* thread_group_native_impl =
             static_cast<ThreadGroupNativeType*>(thread_group_.get());
-        scheduler_thread_group_native_impl->Start(worker_environment);
+        thread_group_native_impl->Start(worker_environment);
         break;
       }
 #endif
@@ -248,8 +249,8 @@
   EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun)));
 }
 
-// Verify that posting tasks after the pool was destroyed fails but doesn't
-// crash.
+// Verify that posting tasks after the thread group was destroyed fails but
+// doesn't crash.
 TEST_P(ThreadGroupTest, PostAfterDestroy) {
   StartThreadGroup();
   auto task_runner = CreateTaskRunner();
@@ -327,15 +328,16 @@
   task_runner->PostTask(
       FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_2_running)));
 
-  // Workers should not be created and tasks should not run before the pool is
-  // started. The sleep is to give time for the tasks to potentially run.
+  // Workers should not be created and tasks should not run before the thread
+  // group is started. The sleep is to give time for the tasks to potentially
+  // run.
   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
   EXPECT_FALSE(task_1_running.IsSignaled());
   EXPECT_FALSE(task_2_running.IsSignaled());
 
   StartThreadGroup();
 
-  // Tasks should run shortly after the pool is started.
+  // Tasks should run shortly after the thread group is started.
   task_1_running.Wait();
   task_2_running.Wait();
 
@@ -372,8 +374,8 @@
 }
 
 // Verify that the maximum number of BEST_EFFORT tasks that can run concurrently
-// in a pool does not affect Sequences with a priority that was increased from
-// BEST_EFFORT to USER_BLOCKING.
+// in a thread group does not affect Sequences with a priority that was
+// increased from BEST_EFFORT to USER_BLOCKING.
 TEST_P(ThreadGroupTest, UpdatePriorityBestEffortToUserBlocking) {
   StartThreadGroup();
 
@@ -420,8 +422,8 @@
     task_runners[i]->UpdatePriority(TaskPriority::USER_BLOCKING);
 
   // Wait until all posted tasks start running. This should not block forever,
-  // even in a pool that enforces a maximum number of concurrent BEST_EFFORT
-  // tasks lower than |kMaxTasks|.
+  // even in a thread group that enforces a maximum number of concurrent
+  // BEST_EFFORT tasks lower than |kMaxTasks|.
   static_assert(kMaxBestEffortTasks < kMaxTasks, "");
   {
     CheckedAutoLock auto_lock(num_tasks_running_lock);
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc
index c0dd277..09955498 100644
--- a/base/task/thread_pool/thread_pool_impl.cc
+++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -77,7 +77,7 @@
       tracked_ref_factory_(this) {
   DCHECK(!histogram_label.empty());
 
-  foreground_pool_ = std::make_unique<ThreadGroupImpl>(
+  foreground_thread_group_ = std::make_unique<ThreadGroupImpl>(
       JoinString(
           {histogram_label, kForegroundPoolEnvironmentParams.name_suffix}, "."),
       kForegroundPoolEnvironmentParams.name_suffix,
@@ -85,7 +85,7 @@
       task_tracker_->GetTrackedRef(), tracked_ref_factory_.GetTrackedRef());
 
   if (CanUseBackgroundPriorityForWorkerThread()) {
-    background_pool_ = std::make_unique<ThreadGroupImpl>(
+    background_thread_group_ = std::make_unique<ThreadGroupImpl>(
         JoinString(
             {histogram_label, kBackgroundPoolEnvironmentParams.name_suffix},
             "."),
@@ -100,9 +100,9 @@
   DCHECK(join_for_testing_returned_.IsSet());
 #endif
 
-  // Reset worker pools to release held TrackedRefs, which block teardown.
-  foreground_pool_.reset();
-  background_pool_.reset();
+  // Reset thread groups to release held TrackedRefs, which block teardown.
+  foreground_thread_group_.reset();
+  background_thread_group_.reset();
 }
 
 void ThreadPoolImpl::Start(const ThreadPool::InitParams& init_params,
@@ -119,11 +119,12 @@
 
 #if defined(OS_WIN) || defined(OS_MACOSX)
   if (FeatureList::IsEnabled(kUseNativeThreadPool)) {
-    std::unique_ptr<ThreadGroup> pool = std::move(foreground_pool_);
-    foreground_pool_ = std::make_unique<ThreadGroupNativeImpl>(
+    std::unique_ptr<ThreadGroup> pool = std::move(foreground_thread_group_);
+    foreground_thread_group_ = std::make_unique<ThreadGroupNativeImpl>(
         task_tracker_->GetTrackedRef(), tracked_ref_factory_.GetTrackedRef(),
         pool.get());
-    pool->InvalidateAndHandoffAllTaskSourcesToOtherPool(foreground_pool_.get());
+    pool->InvalidateAndHandoffAllTaskSourcesToOtherThreadGroup(
+        foreground_thread_group_.get());
   }
 #endif
 
@@ -165,7 +166,7 @@
 
 #if defined(OS_WIN) || defined(OS_MACOSX)
   if (FeatureList::IsEnabled(kUseNativeThreadPool)) {
-    static_cast<ThreadGroupNative*>(foreground_pool_.get())
+    static_cast<ThreadGroupNative*>(foreground_thread_group_.get())
         ->Start(worker_environment);
   } else
 #endif
@@ -176,19 +177,19 @@
     // room for incoming foreground tasks and to minimize the performance impact
     // of best-effort tasks.
 
-    const int max_best_effort_tasks_in_foreground_pool = std::max(
+    const int max_best_effort_tasks_in_foreground_thread_group = std::max(
         1,
         std::min(init_params.background_thread_group_params.max_tasks(),
                  init_params.foreground_thread_group_params.max_tasks() / 2));
-    static_cast<ThreadGroupImpl*>(foreground_pool_.get())
+    static_cast<ThreadGroupImpl*>(foreground_thread_group_.get())
         ->Start(init_params.foreground_thread_group_params,
-                max_best_effort_tasks_in_foreground_pool,
+                max_best_effort_tasks_in_foreground_thread_group,
                 service_thread_task_runner, worker_thread_observer,
                 worker_environment);
   }
 
-  if (background_pool_) {
-    background_pool_->Start(
+  if (background_thread_group_) {
+    background_thread_group_->Start(
         init_params.background_thread_group_params,
         init_params.background_thread_group_params.max_tasks(),
         service_thread_task_runner, worker_thread_observer, worker_environment);
@@ -289,9 +290,9 @@
   // https://crbug.com/771701.
   service_thread_->Stop();
   single_thread_task_runner_manager_.JoinForTesting();
-  foreground_pool_->JoinForTesting();
-  if (background_pool_)
-    background_pool_->JoinForTesting();
+  foreground_thread_group_->JoinForTesting();
+  if (background_thread_group_)
+    background_thread_group_->JoinForTesting();
 #if DCHECK_IS_ON()
   join_for_testing_returned_.Set();
 #endif
@@ -367,11 +368,12 @@
       GetThreadGroupForTraits(task_source_and_transaction.transaction.traits());
 
   if (new_thread_group == current_thread_group) {
-    // |task_source|'s position needs to be updated within its current pool.
+    // |task_source|'s position needs to be updated within its current thread
+    // group.
     current_thread_group->UpdateSortKey(std::move(task_source_and_transaction));
   } else {
-    // |task_source| is changing pools; remove it from its current pool and
-    // reenqueue it.
+    // |task_source| is changing thread groups; remove it from its current
+    // thread group and reenqueue it.
     const bool task_source_was_found = current_thread_group->RemoveTaskSource(
         task_source_and_transaction.task_source);
     if (task_source_was_found) {
@@ -388,11 +390,12 @@
 }
 
 ThreadGroup* ThreadPoolImpl::GetThreadGroupForTraits(const TaskTraits& traits) {
-  if (traits.priority() == TaskPriority::BEST_EFFORT && background_pool_) {
-    return background_pool_.get();
+  if (traits.priority() == TaskPriority::BEST_EFFORT &&
+      background_thread_group_) {
+    return background_thread_group_.get();
   }
 
-  return foreground_pool_.get();
+  return foreground_thread_group_.get();
 }
 
 void ThreadPoolImpl::UpdateCanRunPolicy() {
@@ -403,9 +406,9 @@
                                        : CanRunPolicy::kForegroundOnly)
                : CanRunPolicy::kNone;
   task_tracker_->SetCanRunPolicy(can_run_policy);
-  foreground_pool_->DidUpdateCanRunPolicy();
-  if (background_pool_)
-    background_pool_->DidUpdateCanRunPolicy();
+  foreground_thread_group_->DidUpdateCanRunPolicy();
+  if (background_thread_group_)
+    background_thread_group_->DidUpdateCanRunPolicy();
   single_thread_task_runner_manager_.DidUpdateCanRunPolicy();
 }
 
@@ -417,9 +420,9 @@
 }
 
 void ThreadPoolImpl::ReportHeartbeatMetrics() const {
-  foreground_pool_->ReportHeartbeatMetrics();
-  if (background_pool_)
-    background_pool_->ReportHeartbeatMetrics();
+  foreground_thread_group_->ReportHeartbeatMetrics();
+  if (background_thread_group_)
+    background_thread_group_->ReportHeartbeatMetrics();
 }
 
 }  // namespace internal
diff --git a/base/task/thread_pool/thread_pool_impl.h b/base/task/thread_pool/thread_pool_impl.h
index 3bbd027..00b7d0a 100644
--- a/base/task/thread_pool/thread_pool_impl.h
+++ b/base/task/thread_pool/thread_pool_impl.h
@@ -135,8 +135,8 @@
   // TODO(fdoray): Remove after experiment. https://crbug.com/757022
   AtomicFlag all_tasks_user_blocking_;
 
-  std::unique_ptr<ThreadGroup> foreground_pool_;
-  std::unique_ptr<ThreadGroupImpl> background_pool_;
+  std::unique_ptr<ThreadGroup> foreground_thread_group_;
+  std::unique_ptr<ThreadGroupImpl> background_thread_group_;
 
   // Whether this TaskScheduler was started. Access controlled by
   // |sequence_checker_|.
diff --git a/base/task/thread_pool/thread_pool_impl_unittest.cc b/base/task/thread_pool/thread_pool_impl_unittest.cc
index 50fee5f..a82932b 100644
--- a/base/task/thread_pool/thread_pool_impl_unittest.cc
+++ b/base/task/thread_pool/thread_pool_impl_unittest.cc
@@ -101,7 +101,7 @@
   const bool is_best_effort = (traits.priority() == TaskPriority::BEST_EFFORT);
 
 #if defined(OS_WIN) || defined(OS_MACOSX)
-  // Native thread pools do not provide the ability to name threads.
+  // Native thread groups do not provide the ability to name threads.
   if (pool_type == test::PoolType::NATIVE && !is_single_threaded &&
       !is_best_effort) {
     return;
@@ -914,8 +914,8 @@
 #if defined(OS_WIN) || defined(OS_MACOSX)
   // WorkerThreads are not created (and hence not observed) when using the
   // native thread pools. We still start the ThreadPool in this case since
-  // JoinForTesting is always called on TearDown, and DCHECKs that all worker
-  // pools are started.
+  // JoinForTesting is always called on TearDown, and DCHECKs that all thread
+  // groups are started.
   if (GetParam().pool_type == test::PoolType::NATIVE) {
     StartThreadPool();
     return;
@@ -925,8 +925,8 @@
   testing::StrictMock<test::MockWorkerThreadObserver> observer;
   set_worker_thread_observer(&observer);
 
-  // A worker should be created for each pool. After that, 4 threads should be
-  // created for each SingleThreadTaskRunnerThreadMode (8 on Windows).
+  // A worker should be created for each thread group. After that, 4 threads
+  // should be created for each SingleThreadTaskRunnerThreadMode (8 on Windows).
   const int kExpectedNumPoolWorkers =
       CanUseBackgroundPriorityForWorkerThread() ? 2 : 1;
 #if defined(OS_WIN)
@@ -1007,7 +1007,7 @@
   observer.WaitCallsOnMainExit();
 
   // Join all remaining workers. This should cause shared single-threaded
-  // workers and pool workers to invoke OnWorkerThreadMainExit().
+  // workers and thread pool workers to invoke OnWorkerThreadMainExit().
   observer.AllowCallsOnMainExit(kExpectedNumPoolWorkers +
                                 kExpectedNumSingleThreadedWorkersPerMode);
   TearDown();
@@ -1084,11 +1084,11 @@
 
   ThreadPoolPriorityUpdateTest() : thread_pool_("Test") {}
 
-  void StartThreadPoolWithNumThreadsPerPool(int threads_per_pool) {
+  void StartThreadPoolWithNumThreadsPerGroup(int threads_per_group) {
     constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30);
 
-    thread_pool_.Start({{threads_per_pool, kSuggestedReclaimTime},
-                        {threads_per_pool, kSuggestedReclaimTime}},
+    thread_pool_.Start({{threads_per_group, kSuggestedReclaimTime},
+                        {threads_per_group, kSuggestedReclaimTime}},
                        nullptr);
   }
 
@@ -1111,9 +1111,9 @@
         &task_runners_and_events_.back()->task_ran));
 
     // Task runner that will start as USER_BLOCKING and update to BEST_EFFORT.
-    // Its task is expected to run asynchronously with the other two task
-    // task runners' tasks if background pools exist, or after the USER_VISIBLE
-    // task runner's task if not.
+    // Its task is expected to run asynchronously with the other two task task
+    // runners' tasks if background thread groups exist, or after the
+    // USER_VISIBLE task runner's task if not.
     task_runners_and_events_.push_back(std::make_unique<TaskRunnerAndEvents>(
         thread_pool_.CreateUpdateableSequencedTaskRunnerWithTraitsForTesting(
             TaskTraits({TaskPriority::USER_BLOCKING})),
@@ -1138,10 +1138,10 @@
 // Update the priority of a sequence when it is not scheduled.
 //
 // TODO(adityakeerthi): Parameterize this test once we have a way to prevent
-// sequences from being scheduled without flooding the pool. It is not possible
-// to flood the native pools.
+// sequences from being scheduled without flooding the thread pool. It is not
+// possible to flood the native thread pools.
 TEST_F(ThreadPoolPriorityUpdateTest, UpdatePrioritySequenceNotScheduled) {
-  StartThreadPoolWithNumThreadsPerPool(1);
+  StartThreadPoolWithNumThreadsPerGroup(1);
 
   // Schedule blocking tasks on all threads to prevent tasks from being
   // scheduled later in the test.
@@ -1154,8 +1154,8 @@
         TaskTraits({TaskPriority::BEST_EFFORT})));
   }
 
-  // When all blocking tasks signal |scheduled|, there is a task blocked in
-  // each pool.
+  // When all blocking tasks signal |scheduled|, there is a task blocked in each
+  // thread group.
   for (auto& pool_blocking_event : pool_blocking_events) {
     thread_pool_
         .CreateUpdateableSequencedTaskRunnerWithTraitsForTesting(
@@ -1188,9 +1188,9 @@
         task_runner_and_events->updated_priority);
   }
 
-  // Unblock the task blocking each pool, allowing the posted tasks to run.
-  // Each posted task will verify that it has been posted with updated priority
-  // when it runs.
+  // Unblock the task blocking each thread group, allowing the posted tasks to
+  // run. Each posted task will verify that it has been posted with updated
+  // priority when it runs.
   for (auto& pool_blocking_event : pool_blocking_events) {
     pool_blocking_event->blocked.Signal();
   }
@@ -1212,7 +1212,7 @@
   }
 #endif
 
-  StartThreadPoolWithNumThreadsPerPool(5);
+  StartThreadPoolWithNumThreadsPerGroup(5);
 
   CreateTaskRunnersAndEvents();
 
diff --git a/base/threading/thread_restrictions.cc b/base/threading/thread_restrictions.cc
index 0f33688..b5397f6d 100644
--- a/base/threading/thread_restrictions.cc
+++ b/base/threading/thread_restrictions.cc
@@ -6,25 +6,60 @@
 
 #if DCHECK_IS_ON()
 
+#include "base/debug/stack_trace.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/threading/thread_local.h"
+#include "build/build_config.h"
 
 namespace base {
 
 namespace {
 
-LazyInstance<ThreadLocalBoolean>::Leaky g_blocking_disallowed =
+#if defined(OS_NACL)
+using ThreadLocalBooleanWithStacks = ThreadLocalBoolean;
+#else
+class ThreadLocalBooleanWithStacks {
+ public:
+  ThreadLocalBooleanWithStacks() = default;
+
+  bool Get() const { return bool_.Get(); }
+
+  void Set(bool val) {
+    stack_.Set(std::make_unique<debug::StackTrace>());
+    bool_.Set(val);
+  }
+
+  friend std::ostream& operator<<(std::ostream& out,
+                                  const ThreadLocalBooleanWithStacks& tl) {
+    out << "currently set to " << (tl.bool_.Get() ? "true" : "false") << " by ";
+
+    if (!tl.stack_.Get())
+      return out << "default value\n";
+    out << "\n";
+    tl.stack_.Get()->OutputToStream(&out);
+    return out;
+  }
+
+ private:
+  ThreadLocalBoolean bool_;
+  ThreadLocalOwnedPointer<debug::StackTrace> stack_;
+
+  DISALLOW_COPY_AND_ASSIGN(ThreadLocalBooleanWithStacks);
+};
+#endif  // defined(OS_NACL)
+
+LazyInstance<ThreadLocalBooleanWithStacks>::Leaky g_blocking_disallowed =
     LAZY_INSTANCE_INITIALIZER;
 
-LazyInstance<ThreadLocalBoolean>::Leaky
-    g_singleton_disallowed = LAZY_INSTANCE_INITIALIZER;
-
-LazyInstance<ThreadLocalBoolean>::Leaky g_base_sync_primitives_disallowed =
+LazyInstance<ThreadLocalBooleanWithStacks>::Leaky g_singleton_disallowed =
     LAZY_INSTANCE_INITIALIZER;
 
-LazyInstance<ThreadLocalBoolean>::Leaky g_cpu_intensive_work_disallowed =
-    LAZY_INSTANCE_INITIALIZER;
+LazyInstance<ThreadLocalBooleanWithStacks>::Leaky
+    g_base_sync_primitives_disallowed = LAZY_INSTANCE_INITIALIZER;
+
+LazyInstance<ThreadLocalBooleanWithStacks>::Leaky
+    g_cpu_intensive_work_disallowed = LAZY_INSTANCE_INITIALIZER;
 
 }  // namespace
 
@@ -36,7 +71,11 @@
          "blocking! If this task is running inside the ThreadPool, it needs "
          "to have MayBlock() in its TaskTraits. Otherwise, consider making "
          "this blocking work asynchronous or, as a last resort, you may use "
-         "ScopedAllowBlocking (see its documentation for best practices).";
+         "ScopedAllowBlocking (see its documentation for best practices).\n"
+#if !defined(OS_NACL)
+      << "g_blocking_disallowed " << g_blocking_disallowed.Get()
+#endif
+      ;
 }
 
 }  // namespace internal
@@ -73,7 +112,11 @@
     : was_disallowed_(g_base_sync_primitives_disallowed.Get().Get()) {
   DCHECK(!g_blocking_disallowed.Get().Get())
       << "To allow //base sync primitives in a scope where blocking is "
-         "disallowed use ScopedAllowBaseSyncPrimitivesOutsideBlockingScope.";
+         "disallowed use ScopedAllowBaseSyncPrimitivesOutsideBlockingScope.\n"
+#if !defined(OS_NACL)
+      << "g_blocking_disallowed " << g_blocking_disallowed.Get()
+#endif
+      ;
   g_base_sync_primitives_disallowed.Get().Set(false);
 }
 
@@ -114,7 +157,14 @@
          "prevent jank and deadlock. If waiting on a //base sync primitive is "
          "unavoidable, do it within the scope of a "
          "ScopedAllowBaseSyncPrimitives. If in a test, "
-         "use ScopedAllowBaseSyncPrimitivesForTesting.";
+         "use ScopedAllowBaseSyncPrimitivesForTesting.\n"
+#if !defined(OS_NACL)
+      << "g_base_sync_primitives_disallowed "
+      << g_base_sync_primitives_disallowed.Get()
+      << "It can be useful to know that g_blocking_disallowed is "
+      << g_blocking_disallowed.Get()
+#endif
+      ;
 }
 
 void ResetThreadRestrictionsForTesting() {
@@ -129,7 +179,13 @@
 void AssertLongCPUWorkAllowed() {
   DCHECK(!g_cpu_intensive_work_disallowed.Get().Get())
       << "Function marked as CPU intensive was called from a scope that "
-         "disallows this kind of work! Consider making this work asynchronous.";
+         "disallows this kind of work! Consider making this work "
+         "asynchronous.\n"
+#if !defined(OS_NACL)
+      << "g_cpu_intensive_work_disallowed "
+      << g_cpu_intensive_work_disallowed.Get()
+#endif
+      ;
 }
 
 void DisallowUnresponsiveTasks() {
@@ -161,16 +217,18 @@
 
 // static
 void ThreadRestrictions::AssertSingletonAllowed() {
-  if (g_singleton_disallowed.Get().Get()) {
-    NOTREACHED() << "LazyInstance/Singleton is not allowed to be used on this "
-                 << "thread.  Most likely it's because this thread is not "
-                 << "joinable (or the current task is running with "
-                 << "TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN semantics), so "
-                 << "AtExitManager may have deleted the object on shutdown, "
-                 << "leading to a potential shutdown crash. If you need to use "
-                 << "the object from this context, it'll have to be updated to "
-                 << "use Leaky traits.";
-  }
+  DCHECK(!g_singleton_disallowed.Get().Get())
+      << "LazyInstance/Singleton is not allowed to be used on this thread. "
+         "Most likely it's because this thread is not joinable (or the current "
+         "task is running with TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN "
+         "semantics), so AtExitManager may have deleted the object on "
+         "shutdown, leading to a potential shutdown crash. If you need to use "
+         "the object from this context, it'll have to be updated to use Leaky "
+         "traits.\n"
+#if !defined(OS_NACL)
+      << "g_singleton_disallowed " << g_singleton_disallowed.Get()
+#endif
+      ;
 }
 
 // static
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index 401f2017..30ff6fd 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -22,8 +22,6 @@
 
 #if defined(OS_ANDROID)
 #include "base/android/jni_android.h"
-#elif defined(OS_IOS)
-#include "base/ios/ios_util.h"
 #elif defined(OS_WIN)
 #include <windows.h>
 #endif
@@ -187,19 +185,6 @@
 
 // Test conversions to/from time_t and exploding/unexploding (local time).
 TEST_F(TimeTest, LocalTimeT) {
-#if defined(OS_IOS) && TARGET_OS_SIMULATOR
-  // The function CFTimeZoneCopySystem() fails to determine the system timezone
-  // when running iOS 11.0 simulator on an host running High Sierra and return
-  // the "GMT" timezone. This causes Time::LocalExplode and localtime_r values
-  // to differ by the local timezone offset. Disable the test if simulating
-  // iOS 10.0 as it is not possible to check the version of the host mac.
-  // TODO(crbug.com/782033): remove this once support for iOS pre-11.0 is
-  // dropped or when the bug in CFTimeZoneCopySystem() is fixed.
-  if (ios::IsRunningOnIOS10OrLater() && !ios::IsRunningOnIOS11OrLater()) {
-    return;
-  }
-#endif
-
   // C library time and exploded time.
   time_t now_t_1 = time(nullptr);
   struct tm tms;
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 3bdd85b..c0dc26f 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -83,9 +83,9 @@
 # For unofficial (e.g. development) builds and non-Chrome branded (e.g. Cronet
 # which doesn't use Crashpad, crbug.com/479283) builds it's useful to be able
 # to unwind at runtime.
-exclude_unwind_tables = (is_chrome_branded && is_official_build) ||
-                        (is_chromecast && !is_cast_desktop_build && !is_debug &&
-                         !cast_is_debug && !is_fuchsia)
+exclude_unwind_tables =
+    is_official_build || (is_chromecast && !is_cast_desktop_build &&
+                          !is_debug && !cast_is_debug && !is_fuchsia)
 
 # If true, optimize for size. Does not affect windows builds.
 # Linux & Mac favor speed over size.
@@ -170,12 +170,10 @@
 
 declare_args() {
   # Set to true to use lld, the LLVM linker.
-  # https://crbug.com/911658 for using lld on 32-bit linux.
   # https://crbug.com/917504 for arm chromeos
-  use_lld = is_clang &&
-            (is_win || is_fuchsia || is_android ||
-             (is_linux && target_os != "chromeos" && current_cpu != "x86") ||
-             (target_os == "chromeos" && current_cpu != "arm"))
+  use_lld = is_clang && (is_win || is_fuchsia || is_android ||
+                         (is_linux && target_os != "chromeos") ||
+                         (target_os == "chromeos" && current_cpu != "arm"))
 }
 
 declare_args() {
diff --git a/cc/layers/texture_layer_impl_unittest.cc b/cc/layers/texture_layer_impl_unittest.cc
index eaad5053..13a352cd 100644
--- a/cc/layers/texture_layer_impl_unittest.cc
+++ b/cc/layers/texture_layer_impl_unittest.cc
@@ -56,7 +56,8 @@
   auto resource = viz::TransferableResource::MakeGL(
       gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D,
       gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
-                     gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456));
+                     gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456),
+      layer_size, false /* is_overlay_candidate */);
 
   TextureLayerImpl* texture_layer_impl =
       impl.AddChildToRoot<TextureLayerImpl>();
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index 64697a6c..33bdd003 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -129,11 +129,13 @@
                             base::Unretained(&mock_callback_), mailbox_name2_);
     const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
     const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
-    resource1_ = viz::TransferableResource::MakeGL(
-        mailbox_name1_, GL_LINEAR, arbitrary_target1, sync_token1_);
-    resource2_ = viz::TransferableResource::MakeGL(
-        mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_);
     gfx::Size size(128, 128);
+    resource1_ = viz::TransferableResource::MakeGL(
+        mailbox_name1_, GL_LINEAR, arbitrary_target1, sync_token1_, size,
+        false /* is_overlay_candidate */);
+    resource2_ = viz::TransferableResource::MakeGL(
+        mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_, size,
+        false /* is_overlay_candidate */);
     shared_bitmap_id_ = viz::SharedBitmap::GenerateId();
     sw_release_callback_ = base::BindRepeating(
         &MockReleaseCallback::Release2, base::Unretained(&mock_callback_),
@@ -686,9 +688,11 @@
             &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
             base::Unretained(this), mailbox_char));
 
+    const gfx::Size size(64, 64);
     auto resource = viz::TransferableResource::MakeGL(
         MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
-        SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
+        SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
+        false /* is_overlay_candidate */);
     layer_->SetTransferableResource(resource, std::move(callback));
     // Damage the layer so we send a new frame with the new resource to the
     // Display compositor.
@@ -763,8 +767,10 @@
         viz::SingleReleaseCallback::Create(base::BindOnce(
             &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback,
             base::Unretained(this), sync_token));
+    constexpr gfx::Size size(64, 64);
     auto resource = viz::TransferableResource::MakeGL(
-        MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D, sync_token);
+        MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D, sync_token,
+        size, false /* is_overlay_candidate */);
     layer_->SetTransferableResource(resource, std::move(callback));
   }
 
@@ -1023,9 +1029,10 @@
       return true;
     }
 
-    *resource = viz::TransferableResource::MakeGL(MailboxFromChar('1'),
-                                                  GL_LINEAR, GL_TEXTURE_2D,
-                                                  SyncTokenFromUInt(0x123));
+    constexpr gfx::Size size(64, 64);
+    *resource = viz::TransferableResource::MakeGL(
+        MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D,
+        SyncTokenFromUInt(0x123), size, false /* is_overlay_candidate */);
     *release_callback = viz::SingleReleaseCallback::Create(base::BindOnce(
         &TextureLayerNoExtraCommitForMailboxTest::ResourceReleased,
         base::Unretained(this)));
@@ -1107,9 +1114,11 @@
   }
 
   viz::TransferableResource MakeResource(char name) {
+    constexpr gfx::Size size(64, 64);
     return viz::TransferableResource::MakeGL(
         MailboxFromChar(name), GL_LINEAR, GL_TEXTURE_2D,
-        SyncTokenFromUInt(static_cast<uint32_t>(name)));
+        SyncTokenFromUInt(static_cast<uint32_t>(name)), size,
+        false /* is_overlay_candidate */);
   }
 
   void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
@@ -1216,8 +1225,10 @@
       SharedBitmapIdRegistrar* bitmap_registrar,
       viz::TransferableResource* resource,
       std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override {
+    constexpr gfx::Size size(64, 64);
     *resource = viz::TransferableResource::MakeGL(
-        MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D, SyncTokenFromUInt(1));
+        MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D, SyncTokenFromUInt(1),
+        size, false /* is_overlay_candidate */);
     *release_callback = viz::SingleReleaseCallback::Create(
         base::BindOnce(&TextureLayerReleaseResourcesBase::ResourceReleased,
                        base::Unretained(this)));
@@ -1293,9 +1304,11 @@
         viz::SingleReleaseCallback::Create(base::BindOnce(
             &TextureLayerWithResourceMainThreadDeleted::ReleaseCallback,
             base::Unretained(this)));
+    constexpr gfx::Size size(64, 64);
     auto resource = viz::TransferableResource::MakeGL(
         MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
-        SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
+        SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
+        false /* is_overlay_candidate */);
     layer_->SetTransferableResource(resource, std::move(callback));
   }
 
@@ -1363,9 +1376,11 @@
         viz::SingleReleaseCallback::Create(base::BindOnce(
             &TextureLayerWithResourceImplThreadDeleted::ReleaseCallback,
             base::Unretained(this)));
+    constexpr gfx::Size size(64, 64);
     auto resource = viz::TransferableResource::MakeGL(
         MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
-        SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
+        SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
+        false /* is_overlay_candidate */);
     layer_->SetTransferableResource(resource, std::move(callback));
   }
 
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc
index 7818ee1..9c73860 100644
--- a/cc/resources/resource_pool.cc
+++ b/cc/resources/resource_pool.cc
@@ -321,7 +321,7 @@
       resource->mark_avoid_reuse();
       return false;
     }
-    transferable = viz::TransferableResource::MakeGLOverlay(
+    transferable = viz::TransferableResource::MakeGL(
         gpu_backing->mailbox, GL_LINEAR, gpu_backing->texture_target,
         gpu_backing->mailbox_sync_token, resource->size(),
         gpu_backing->overlay_candidate);
diff --git a/cc/test/fake_ui_resource_layer_tree_host_impl.cc b/cc/test/fake_ui_resource_layer_tree_host_impl.cc
index 2022b67..2dbade6b 100644
--- a/cc/test/fake_ui_resource_layer_tree_host_impl.cc
+++ b/cc/test/fake_ui_resource_layer_tree_host_impl.cc
@@ -26,8 +26,9 @@
   UIResourceData data;
 
   data.resource_id_for_export = resource_provider()->ImportResource(
-      viz::TransferableResource::MakeGL(gpu::Mailbox::Generate(), GL_LINEAR,
-                                        GL_TEXTURE_2D, gpu::SyncToken()),
+      viz::TransferableResource::MakeGL(
+          gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+          bitmap.GetSize(), false /* is_overlay_candidate */),
       viz::SingleReleaseCallback::Create(base::DoNothing()));
 
   data.opaque = bitmap.GetOpaque();
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc
index b43730d..62c62f65 100644
--- a/cc/test/render_pass_test_utils.cc
+++ b/cc/test/render_pass_test_utils.cc
@@ -33,8 +33,10 @@
     viz::ClientResourceProvider* resource_provider,
     const gpu::SyncToken& sync_token,
     gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB()) {
+  constexpr gfx::Size size(64, 64);
   auto transfer_resource = viz::TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, sync_token);
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, sync_token, size,
+      false /* is_overlay_candidate */);
   transfer_resource.color_space = std::move(color_space);
   return resource_provider->ImportResource(
       transfer_resource, viz::SingleReleaseCallback::Create(base::DoNothing()));
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 8cc53a18..e09d1b99 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -5444,7 +5444,7 @@
                                     ->SharedImageInterface()
                                     ->GenUnverifiedSyncToken();
 
-    transferable = viz::TransferableResource::MakeGLOverlay(
+    transferable = viz::TransferableResource::MakeGL(
         mailbox, GL_LINEAR, texture_target, sync_token, upload_size,
         overlay_candidate);
     transferable.format = format;
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc
index 35953305..92fd357 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -330,8 +330,11 @@
                                    gpu::CommandBufferId::FromUnsafeValue(1),
                                    next_fence_sync_);
     next_sync_token.SetVerifyFlush();
+
+    constexpr gfx::Size size(64, 64);
     viz::TransferableResource resource = viz::TransferableResource::MakeGL(
-        gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, next_sync_token);
+        gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, next_sync_token, size,
+        false /* is_overlay_candidate */);
     next_fence_sync_++;
 
     tab_contents_->SetTransferableResource(resource, std::move(callback));
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 1f06634..a06f23d 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -934,8 +934,10 @@
         TextureLayer::CreateForMailbox(nullptr);
     texture->SetBounds(gfx::Size(10, 10));
     texture->SetIsDrawable(true);
+    constexpr gfx::Size size(64, 64);
     auto resource = viz::TransferableResource::MakeGL(
-        mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token);
+        mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token, size,
+        false /* is_overlay_candidate */);
     texture->SetTransferableResource(
         resource, viz::SingleReleaseCallback::Create(base::BindOnce(
                       &LayerTreeHostContextTestDontUseLostResources::
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 99c043b..e26a2ee 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -2381,6 +2381,7 @@
     "java/src/org/chromium/chrome/browser/browsing_data/UrlFilterBridge.java",
     "java/src/org/chromium/chrome/browser/childaccounts/ChildAccountFeedbackReporter.java",
     "java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java",
+    "java/src/org/chromium/chrome/browser/complex_tasks/TaskTabHelper.java",
     "java/src/org/chromium/chrome/browser/component_updater/UpdateScheduler.java",
     "java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java",
     "java/src/org/chromium/chrome/browser/compositor/CompositorView.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 15d3efd..32dea83 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -170,6 +170,7 @@
   "java/src/org/chromium/chrome/browser/browsing_data/UrlFilters.java",
   "java/src/org/chromium/chrome/browser/childaccounts/ChildAccountFeedbackReporter.java",
   "java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java",
+  "java/src/org/chromium/chrome/browser/complex_tasks/TaskTabHelper.java",
   "java/src/org/chromium/chrome/browser/component_updater/UpdateScheduler.java",
   "java/src/org/chromium/chrome/browser/component_updater/UpdateTask.java",
   "java/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManager.java",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
index 3d96cb01..1703c77e 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -4,8 +4,6 @@
 
 package org.chromium.chrome.browser.autofill_assistant;
 
-import static org.chromium.chrome.browser.autofill_assistant.carousel.AssistantCarouselModel.ALIGNMENT;
-
 import android.support.annotation.Nullable;
 
 import org.chromium.base.annotations.CalledByNative;
@@ -229,7 +227,6 @@
                     disabled[i], () -> safeNativeOnSuggestionSelected(suggestionIndex)));
         }
         AssistantCarouselModel model = getModel().getSuggestionsModel();
-        model.set(ALIGNMENT, AssistantCarouselModel.Alignment.START);
         setChips(model, chips);
     }
 
@@ -284,10 +281,6 @@
     @CalledByNative
     private void setActions(List<AssistantChip> chips) {
         AssistantCarouselModel model = getModel().getActionsModel();
-        model.set(ALIGNMENT,
-                (chips.size() == 1 && chips.get(0).getType() != Type.BUTTON_FILLED_BLUE)
-                        ? AssistantCarouselModel.Alignment.CENTER
-                        : AssistantCarouselModel.Alignment.END);
         setChips(model, chips);
     }
 
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantCarouselModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantCarouselModel.java
index 751c5fc..4360e0ee 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantCarouselModel.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantCarouselModel.java
@@ -4,34 +4,14 @@
 
 package org.chromium.chrome.browser.autofill_assistant.carousel;
 
-import android.support.annotation.IntDef;
-
 import org.chromium.ui.modelutil.ListModel;
-import org.chromium.ui.modelutil.PropertyModel;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 
 /**
  * State for the carousel of the Autofill Assistant.
  */
-public class AssistantCarouselModel extends PropertyModel {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({Alignment.START, Alignment.CENTER, Alignment.END})
-    public @interface Alignment {
-        int START = 0;
-        int CENTER = 1;
-        int END = 2;
-    }
-
-    public static final WritableIntPropertyKey ALIGNMENT = new WritableIntPropertyKey();
-
+public class AssistantCarouselModel {
     private final ListModel<AssistantChip> mChipsModel = new ListModel<>();
 
-    public AssistantCarouselModel() {
-        super(ALIGNMENT);
-    }
-
     public ListModel<AssistantChip> getChipsModel() {
         return mChipsModel;
     }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantSuggestionsCarouselCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantSuggestionsCarouselCoordinator.java
index 7fc8446..4e6c254 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantSuggestionsCarouselCoordinator.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantSuggestionsCarouselCoordinator.java
@@ -24,8 +24,6 @@
     private final LinearLayoutManager mLayoutManager;
     private final RecyclerView mView;
 
-    private boolean mCentered;
-
     public AssistantSuggestionsCarouselCoordinator(Context context, AssistantCarouselModel model) {
         mLayoutManager = new LinearLayoutManager(
                 context, LinearLayoutManager.HORIZONTAL, /* reverseLayout= */ false);
@@ -41,29 +39,6 @@
                         AssistantChipViewHolder::getViewType, AssistantChipViewHolder::bind),
                 AssistantChipViewHolder::create));
 
-        // Listen for changes on REVERSE_LAYOUT.
-        model.addObserver((source, propertyKey) -> {
-            if (AssistantCarouselModel.ALIGNMENT == propertyKey) {
-                switch (model.get(AssistantCarouselModel.ALIGNMENT)) {
-                    case AssistantCarouselModel.Alignment.START:
-                        mLayoutManager.setReverseLayout(false);
-                        mCentered = false;
-                        break;
-                    case AssistantCarouselModel.Alignment.CENTER:
-                        mCentered = true;
-                        mView.invalidateItemDecorations();
-                        break;
-                    case AssistantCarouselModel.Alignment.END:
-                        mLayoutManager.setReverseLayout(true);
-                        mCentered = false;
-                        break;
-                }
-            } else {
-                assert false : "Unhandled property detected in AssistantCarouselCoordinator!";
-            }
-        });
-
-        // Listen for changes on chips, and set visibility accordingly.
         model.getChipsModel().addObserver(new AbstractListObserver<Void>() {
             @Override
             public void onDataSetChanged() {
@@ -104,24 +79,6 @@
         @Override
         public void getItemOffsets(
                 Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
-            // We use RecyclerView.State#getItemCount() as it returns the correct value when the
-            // carousel is being animated.
-            if (mCentered && state.getItemCount() == 1) {
-                // We have one view and want it horizontally centered. By this time the parent
-                // measured width is correct (as it matches its parent), but we need to explicitly
-                // measure how big the chip view wants to be.
-                int availableWidth = parent.getMeasuredWidth();
-                view.measure(
-                        View.MeasureSpec.makeMeasureSpec(availableWidth, View.MeasureSpec.AT_MOST),
-                        View.MeasureSpec.makeMeasureSpec(
-                                parent.getMeasuredHeight(), View.MeasureSpec.UNSPECIFIED));
-
-                int margin = (availableWidth - view.getMeasuredWidth()) / 2;
-                outRect.left = margin;
-                outRect.right = margin;
-                return;
-            }
-
             int position = parent.getChildAdapterPosition(view);
 
             // If old position != NO_POSITION, it means the carousel is being animated and we should
@@ -143,6 +100,8 @@
                 left = mInnerSpacePx;
             }
 
+            // We use RecyclerView.State#getItemCount() as it returns the correct value when the
+            // carousel is being animated.
             if (position == state.getItemCount() - 1) {
                 right = mOuterSpacePx;
             } else {
diff --git a/chrome/android/java/res/xml/sync_and_services_preferences.xml b/chrome/android/java/res/xml/sync_and_services_preferences.xml
index 5696a5cb..d4ee2a1 100644
--- a/chrome/android/java/res/xml/sync_and_services_preferences.xml
+++ b/chrome/android/java/res/xml/sync_and_services_preferences.xml
@@ -12,6 +12,10 @@
         android:key="sign_in"
         android:title="@string/sign_in_to_chrome"/>
 
+    <org.chromium.chrome.browser.preferences.ChromeBasePreference
+        android:key="manage_your_google_account"
+        android:title="@string/manage_your_google_account"/>
+
     <PreferenceCategory
         android:key="sync_category"
         android:title="@string/sync_category_title">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
index 14234e0d..7f5cfd5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
@@ -483,4 +483,9 @@
      * ChromeActivity initialization.
      */
     public void startSystemSettingsObserver() {}
+
+    /**
+     * Initializes the lifecycle tracker for Touchless mode.
+     */
+    public void initTouchlessLifecycleTracker() {}
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
index 12ab43c..67f2f1f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -133,6 +133,8 @@
             // Disable MemoryPressureMonitor polling when Chrome goes to the background.
             ApplicationStatus.registerApplicationStateListener(
                     ChromeApplication::updateMemoryPressurePolling);
+
+            AppHooks.get().initTouchlessLifecycleTracker();
         }
 
         // Write installed modules to crash keys. This needs to be done as early as possible so that
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/complex_tasks/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/complex_tasks/OWNERS
new file mode 100644
index 0000000..1f20234
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/complex_tasks/OWNERS
@@ -0,0 +1,3 @@
+wychen@chromium.org
+yusufo@chromium.org
+bsep@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/complex_tasks/TaskTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/complex_tasks/TaskTabHelper.java
new file mode 100644
index 0000000..890a7845
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/complex_tasks/TaskTabHelper.java
@@ -0,0 +1,51 @@
+// 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.complex_tasks;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabAttributeKeys;
+import org.chromium.chrome.browser.tab.TabAttributes;
+import org.chromium.content_public.browser.WebContents;
+
+/**
+ * Used for maintaining Task ID (see ContextRecordTaskId) data about a Tab
+ */
+@JNINamespace("tasks")
+public class TaskTabHelper {
+    private static final long INVALID_ID = -1;
+
+    private TaskTabHelper() {}
+
+    /**
+     * Creates the {@link TaskTabHelper} for the given {@link Tab}.
+     * @param tab the Tab to attach the helper to.
+     * @param parentTab corresponding parent Tab for the Tab
+     */
+    public static void createForTab(Tab tab, Tab parentTab) {
+        if (parentTab == null) return;
+        TabAttributes.from(tab).set(
+                TabAttributeKeys.PARENT_TAB_TASK_ID, nativeGetTaskId(parentTab.getWebContents()));
+        TabAttributes.from(tab).set(TabAttributeKeys.PARENT_TAB_ROOT_TASK_ID,
+                nativeGetRootTaskId(parentTab.getWebContents()));
+    }
+
+    @CalledByNative
+    private static long getParentTaskId(Tab tab) {
+        Long parentTaskId = TabAttributes.from(tab).get(TabAttributeKeys.PARENT_TAB_TASK_ID);
+        return parentTaskId == null ? INVALID_ID : parentTaskId;
+    }
+
+    @CalledByNative
+    private static long getParentRootTaskId(Tab tab) {
+        Long parentRootTaskId =
+                TabAttributes.from(tab).get(TabAttributeKeys.PARENT_TAB_ROOT_TASK_ID);
+        return parentRootTaskId == null ? INVALID_ID : parentRootTaskId;
+    }
+
+    private static native long nativeGetTaskId(WebContents webContents);
+    private static native long nativeGetRootTaskId(WebContents webContents);
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java
index 0b5ca287..957331e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java
@@ -254,7 +254,7 @@
      * @param searchTerm The string that represents the search term to display.
      */
     public void updateForDictionaryDefinition(String searchTerm) {
-        if (!mCardIconControl.canUpdateControlsForDefinition(
+        if (!mCardIconControl.didUpdateControlsForDefinition(
                     mContextControl, mImageControl, searchTerm)) {
             // Can't style, just update with the text to display.
             setSearchTerm(searchTerm);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCardIconControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCardIconControl.java
index 3e54021..5270ca4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCardIconControl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCardIconControl.java
@@ -43,7 +43,7 @@
      *        dictionary icon here.
      * @param searchTerm The string that represents the search term to display.
      */
-    boolean canUpdateControlsForDefinition(ContextualSearchContextControl contextControl,
+    boolean didUpdateControlsForDefinition(ContextualSearchContextControl contextControl,
             ContextualSearchImageControl imageControl, String searchTerm) {
         // This middle-dot character is returned by the server and marks the beginning of the
         // pronunciation.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
index 5ef37be29..969f600 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -580,7 +580,8 @@
     public void onSearchTermResolved(String searchTerm, String thumbnailUrl, String quickActionUri,
             int quickActionCategory, @CardTag int cardTagEnum) {
         mPanelMetrics.onSearchTermResolved();
-        if (cardTagEnum == CardTag.CT_DEFINITION) {
+        if (cardTagEnum == CardTag.CT_DEFINITION
+                || cardTagEnum == CardTag.CT_CONTEXTUAL_DEFINITION) {
             getSearchBarControl().updateForDictionaryDefinition(searchTerm);
             return;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java
index 1a24499..62ce896 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java
@@ -62,6 +62,7 @@
      */
     private SelectionClientManager mSelectionClientManager;
 
+    /** The pointer to our native C++ implementation. */
     private long mNativeHelper;
 
     /** {@code true} while observing other overlay panel via {@link OverlayPanelManagerObserver} */
@@ -73,6 +74,9 @@
      */
     private Tab mUnhookedTab;
 
+    /** Whether the current default search engine is Google.  Is {@code null} if not inited. */
+    private Boolean mIsDefaultSearchEngineGoogle;
+
     /**
      * Creates a contextual search tab helper for the given tab.
      * @param tab The tab whose contextual search actions will be handled by this helper.
@@ -202,7 +206,13 @@
             mTemplateUrlObserver = new TemplateUrlServiceObserver() {
                 @Override
                 public void onTemplateURLServiceChanged() {
-                    updateContextualSearchHooks(mWebContents);
+                    boolean isDefaultSearchEngineGoogle =
+                            TemplateUrlService.getInstance().isDefaultSearchEngineGoogle();
+                    if (mIsDefaultSearchEngineGoogle == null
+                            || isDefaultSearchEngineGoogle != mIsDefaultSearchEngineGoogle) {
+                        mIsDefaultSearchEngineGoogle = isDefaultSearchEngineGoogle;
+                        updateContextualSearchHooks(mWebContents);
+                    }
                 }
             };
             TemplateUrlService.getInstance().addObserver(mTemplateUrlObserver);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java
index 1c9b763..d415e85 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java
@@ -47,11 +47,6 @@
 
     public PrefetchBackgroundTask() {}
 
-    protected Profile getProfile() {
-        if (mProfile == null) mProfile = Profile.getLastUsedProfile();
-        return mProfile;
-    }
-
     @Override
     public @StartBeforeNativeResult int onStartTaskBeforeNativeLoaded(
             Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
@@ -113,7 +108,7 @@
             return;
         }
 
-        nativeStartPrefetchTask(getProfile(), mGcmToken);
+        nativeStartPrefetchTask(mGcmToken);
     }
 
     private boolean isBrowserRunningInReducedMode() {
@@ -206,7 +201,7 @@
     }
 
     @VisibleForTesting
-    native boolean nativeStartPrefetchTask(Profile profile, String gcmToken);
+    native boolean nativeStartPrefetchTask(String gcmToken);
     @VisibleForTesting
     native boolean nativeOnStopTask(long nativePrefetchBackgroundTaskAndroid);
     native void nativeSetTaskReschedulingForTesting(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
index b55e7429..785b603 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
@@ -75,6 +75,7 @@
     private static final String FRAGMENT_CANCEL_SYNC = "cancel_sync_dialog";
 
     private static final String PREF_SIGNIN = "sign_in";
+    private static final String PREF_MANAGE_YOUR_GOOGLE_ACCOUNT = "manage_your_google_account";
 
     private static final String PREF_SYNC_CATEGORY = "sync_category";
     private static final String PREF_SYNC_ERROR_CARD = "sync_error_card";
@@ -113,6 +114,7 @@
     private boolean mIsFromSigninScreen;
 
     private SignInPreference mSigninPreference;
+    private Preference mManageYourGoogleAccount;
 
     private PreferenceCategory mSyncCategory;
     private Preference mSyncErrorCard;
@@ -163,6 +165,9 @@
 
         mSigninPreference = (SignInPreference) findPreference(PREF_SIGNIN);
         mSigninPreference.setPersonalizedPromoEnabled(false);
+        mManageYourGoogleAccount = findPreference(PREF_MANAGE_YOUR_GOOGLE_ACCOUNT);
+        mManageYourGoogleAccount.setOnPreferenceClickListener(SyncPreferenceUtils.toOnClickListener(
+                this, () -> SyncPreferenceUtils.openGoogleMyAccount(getActivity())));
 
         mSyncCategory = (PreferenceCategory) findPreference(PREF_SYNC_CATEGORY);
         mSyncErrorCard = findPreference(PREF_SYNC_ERROR_CARD);
@@ -521,9 +526,11 @@
         }
 
         if (!ChromeSigninController.get().isSignedIn()) {
+            getPreferenceScreen().removePreference(mManageYourGoogleAccount);
             getPreferenceScreen().removePreference(mSyncCategory);
             return;
         }
+        getPreferenceScreen().addPreference(mManageYourGoogleAccount);
         getPreferenceScreen().addPreference(mSyncCategory);
 
         mCurrentSyncError = getSyncError();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreferenceUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreferenceUtils.java
index 571aaeda..63cec44 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreferenceUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreferenceUtils.java
@@ -35,6 +35,8 @@
  */
 public class SyncPreferenceUtils {
     private static final String DASHBOARD_URL = "https://www.google.com/settings/chrome/sync";
+    private static final String MY_ACCOUNT_URL =
+            "https://accounts.google.com/AccountChooser?Email=%s&continue=https://myaccount.google.com/";
 
     /**
      * Checks if sync error icon should be shown. Show sync error icon if sync is off because
@@ -176,14 +178,14 @@
     }
 
     /**
-     * Opens web dashboard to manage sync in a custom tab.
+     * Opens web dashboard to specified url in a custom tab.
      * @param activity The activity to use for starting the intent.
+     * @param url The url link to open in the custom tab.
      */
-    public static void openSyncDashboard(Activity activity) {
-        // TODO(https://crbug.com/948103): Create a builder for custom tab intents.
+    private static void openCustomTabWithURL(Activity activity, String url) {
         CustomTabsIntent customTabIntent =
                 new CustomTabsIntent.Builder().setShowTitle(false).build();
-        customTabIntent.intent.setData(Uri.parse(DASHBOARD_URL));
+        customTabIntent.intent.setData(Uri.parse(url));
 
         Intent intent = LaunchIntentDispatcher.createCustomTabActivityIntent(
                 activity, customTabIntent.intent);
@@ -195,4 +197,24 @@
 
         IntentUtils.safeStartActivity(activity, intent);
     }
+
+    /**
+     * Opens web dashboard to manage sync in a custom tab.
+     * @param activity The activity to use for starting the intent.
+     */
+    public static void openSyncDashboard(Activity activity) {
+        // TODO(https://crbug.com/948103): Create a builder for custom tab intents.
+        openCustomTabWithURL(activity, DASHBOARD_URL);
+    }
+
+    /**
+     * Opens web dashboard to manage google account in a custom tab.
+     * @param activity The activity to use for starting the intent.
+     */
+    public static void openGoogleMyAccount(Activity activity) {
+        assert ChromeSigninController.get().isSignedIn();
+        openCustomTabWithURL(activity,
+                String.format(
+                        MY_ACCOUNT_URL, ChromeSigninController.get().getSignedInAccountName()));
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index d25b717..100dc3c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -332,7 +332,7 @@
         mPendingLoadParams = loadUrlParams;
         if (loadUrlParams != null) mUrl = loadUrlParams.getUrl();
 
-        TabHelpers.initTabHelpers(this, creationState);
+        TabHelpers.initTabHelpers(this, parent, creationState);
 
         mAttachStateChangeListener = new OnAttachStateChangeListener() {
             @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabAttributeKeys.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabAttributeKeys.java
index 5141d9af..3b0e896 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabAttributeKeys.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabAttributeKeys.java
@@ -20,4 +20,12 @@
 
     /** Whether tab modal dialog is showing or not. */
     public static final String MODAL_DIALOG_SHOWING = "isTabModalDialogShowing";
+
+    /** Parent Tab Task Id. See ContextRecordTaskId (context_record_task_id.h) for definition */
+    public static final String PARENT_TAB_TASK_ID = "ParentTaskId";
+
+    /**
+     * Parent Tab Root Task Id. See ContextRecordTaskId (context_record_task_id.h) for definition
+     */
+    public static final String PARENT_TAB_ROOT_TASK_ID = "ParentRootTaskId";
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java
index bd0546b..bd2429f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java
@@ -7,6 +7,7 @@
 import org.chromium.chrome.browser.ChromeActionModeCallback;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.SwipeRefreshHandler;
+import org.chromium.chrome.browser.complex_tasks.TaskTabHelper;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchTabHelper;
 import org.chromium.chrome.browser.crypto.CipherFactory;
 import org.chromium.chrome.browser.infobar.InfoBarContainer;
@@ -26,9 +27,10 @@
     /**
      * Creates Tab helper objects upon Tab creation.
      * @param tab {@link Tab} to create helpers for.
+     * @param parentTab {@link Tab} parent tab
      * @param creationState State in which the tab is created.
      */
-    static void initTabHelpers(Tab tab, @TabCreationState Integer creationState) {
+    static void initTabHelpers(Tab tab, Tab parentTab, @TabCreationState Integer creationState) {
         if (creationState != null) TabUma.create(tab, creationState);
         TabThemeColorHelper.createForTab(tab);
         TabFullscreenHandler.createForTab(tab);
@@ -39,6 +41,7 @@
             TaskRecognizer.createForTab(tab);
         }
         MediaSessionTabHelper.createForTab(tab);
+        TaskTabHelper.createForTab(tab, parentTab);
 
         // TODO(jinsukkim): Do this by having something observe new tab creation.
         if (tab.isIncognito()) CipherFactory.getInstance().triggerKeyGeneration();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java
index cd953f56..52fac19 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java
@@ -585,16 +585,14 @@
         Intent shareIntent = new Intent();
         shareIntent.setAction(Intent.ACTION_SEND);
         shareIntent.setPackage(webApkPackageName);
-        shareIntent.setType("text/plain");
+        shareIntent.setType("*/*");
         List<ResolveInfo> resolveInfos =
                 ContextUtils.getApplicationContext().getPackageManager().queryIntentActivities(
                         shareIntent, PackageManager.GET_META_DATA);
 
         for (ResolveInfo resolveInfo : resolveInfos) {
             Bundle shareTargetMetaData = resolveInfo.activityInfo.metaData;
-            if (shareTargetMetaData == null
-                    || WebApkShareTargetUtil.methodFromShareTargetMetaDataIsPost(
-                            shareTargetMetaData)) {
+            if (shareTargetMetaData == null) {
                 continue;
             }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java
index d594627a..4923cff 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java
@@ -17,9 +17,10 @@
         if (postData == null) {
             return false;
         }
-        nativeLoadViewForShareTargetPost(postData.isMultipartEncoding, postData.names,
-                postData.values, postData.filenames, postData.types, webApkInfo.uri().toString(),
-                webContents);
+        nativeLoadViewForShareTargetPost(postData.isMultipartEncoding,
+                postData.names.toArray(new String[0]), postData.values.toArray(new byte[0][]),
+                postData.filenames.toArray(new String[0]), postData.types.toArray(new String[0]),
+                webApkInfo.uri().toString(), webContents);
         return true;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtil.java
index e5dd9a4..15b2a1c6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtil.java
@@ -36,10 +36,25 @@
     // A class containing data required to generate a share target post request.
     protected static class PostData {
         public boolean isMultipartEncoding;
-        public String[] names;
-        public byte[][] values;
-        public String[] filenames;
-        public String[] types;
+        public ArrayList<String> names;
+        public ArrayList<byte[]> values;
+        public ArrayList<String> filenames;
+        public ArrayList<String> types;
+
+        public PostData(boolean isMultipartEncoding) {
+            this.isMultipartEncoding = isMultipartEncoding;
+            names = new ArrayList<>();
+            values = new ArrayList<>();
+            filenames = new ArrayList<>();
+            types = new ArrayList<>();
+        }
+
+        private void add(String name, byte[] value, String fileName, String type) {
+            names.add(name);
+            values.add(value);
+            filenames.add(fileName);
+            types.add(type);
+        }
     }
 
     private static Bundle computeShareTargetMetaData(
@@ -125,49 +140,32 @@
         return originalData;
     }
 
-    protected static PostData computeMultipartPostData(
-            Bundle shareTargetMetaData, WebApkInfo.ShareData shareData) {
-        String nameString = IntentUtils.safeGetString(
-                shareTargetMetaData, WebApkMetaDataKeys.SHARE_PARAM_NAMES);
-        String acceptString = IntentUtils.safeGetString(
-                shareTargetMetaData, WebApkMetaDataKeys.SHARE_PARAM_ACCEPTS);
-        ArrayList<Uri> fileUris = shareData.files;
+    protected static boolean methodFromShareTargetMetaDataIsPost(Bundle metaData) {
+        String method = IntentUtils.safeGetString(metaData, WebApkMetaDataKeys.SHARE_METHOD);
+        return method != null && "POST".equals(method.toUpperCase(Locale.ENGLISH));
+    }
 
-        if (nameString == null || acceptString == null) {
-            return null;
+    protected static void addFilesToMultipartPostData(PostData postData, String encodedFileNames,
+            String encodedFileAccepts, ArrayList<Uri> shareFiles) {
+        if (encodedFileNames == null || encodedFileAccepts == null || shareFiles == null) {
+            return;
         }
 
-        if (fileUris == null) {
-            return null;
-        }
         ArrayList<String> names;
         ArrayList<ArrayList<String>> accepts;
-
         try {
-            names = decodeJsonStringArray(new JSONArray(nameString));
+            names = decodeJsonStringArray(new JSONArray(encodedFileNames));
+            accepts = decodeJsonAccepts(encodedFileAccepts);
         } catch (JSONException e) {
-            return null;
-        }
-
-        try {
-            accepts = decodeJsonAccepts(acceptString);
-        } catch (JSONException e) {
-            return null;
+            return;
         }
 
         if (names.size() != accepts.size()) {
-            return null;
+            return;
         }
 
-        PostData postData = new PostData();
-        postData.isMultipartEncoding = true;
-        ArrayList<String> shareNames = new ArrayList<>();
-        ArrayList<byte[]> shareValues = new ArrayList<>();
-        ArrayList<String> shareFilenames = new ArrayList<>();
-        ArrayList<String> shareTypes = new ArrayList<>();
-
         try (StrictModeContext strictModeContextUnused = StrictModeContext.allowDiskReads()) {
-            for (Uri fileUri : fileUris) {
+            for (Uri fileUri : shareFiles) {
                 String fileType = getFileTypeFromContentUri(fileUri);
                 String fileName = getFileNameFromContentUri(fileUri);
 
@@ -181,55 +179,13 @@
                     if (mimeTypeFilter.accept(fileUri, fileType)) {
                         byte[] fileContent = readStringFromContentUri(fileUri);
                         if (fileContent != null) {
-                            shareNames.add(names.get(i));
-                            shareValues.add(fileContent);
-                            shareFilenames.add(fileName);
-                            shareTypes.add(fileType);
+                            postData.add(names.get(i), fileContent, fileName, fileType);
                         }
                         break;
                     }
                 }
             }
         }
-        postData.names = shareNames.toArray(new String[0]);
-        postData.values = shareValues.toArray(new byte[0][]);
-        postData.filenames = shareFilenames.toArray(new String[0]);
-        postData.types = shareTypes.toArray(new String[0]);
-        return postData;
-    }
-
-    protected static PostData computeUrlEncodedPostData(
-            Bundle shareTargetMetaData, WebApkInfo.ShareData shareData) {
-        PostData postData = new PostData();
-        postData.isMultipartEncoding = false;
-        postData.filenames = new String[0];
-        postData.types = new String[0];
-
-        ArrayList<String> names = new ArrayList<>();
-        ArrayList<byte[]> values = new ArrayList<>();
-
-        String shareTitleName = IntentUtils.safeGetString(
-                shareTargetMetaData, WebApkMetaDataKeys.SHARE_PARAM_TITLE);
-        String shareTextName =
-                IntentUtils.safeGetString(shareTargetMetaData, WebApkMetaDataKeys.SHARE_PARAM_TEXT);
-
-        if (shareTitleName != null && shareData.subject != null) {
-            names.add(shareTitleName);
-            values.add(ApiCompatibilityUtils.getBytesUtf8(shareData.subject));
-        }
-        if (shareTextName != null && shareData.text != null) {
-            names.add(shareTextName);
-            values.add(ApiCompatibilityUtils.getBytesUtf8(shareData.text));
-        }
-
-        postData.names = names.toArray(new String[0]);
-        postData.values = values.toArray(new byte[0][]);
-        return postData;
-    }
-
-    protected static boolean methodFromShareTargetMetaDataIsPost(Bundle metaData) {
-        String method = IntentUtils.safeGetString(metaData, WebApkMetaDataKeys.SHARE_METHOD);
-        return method != null && "POST".equals(method.toUpperCase(Locale.ENGLISH));
     }
 
     protected static PostData computePostData(
@@ -239,9 +195,34 @@
                 || !methodFromShareTargetMetaDataIsPost(shareTargetMetaData)) {
             return null;
         }
-        if (enctypeFromMetaDataIsMultipart(shareTargetMetaData)) {
-            return computeMultipartPostData(shareTargetMetaData, shareData);
+
+        PostData postData = new PostData(enctypeFromMetaDataIsMultipart(shareTargetMetaData));
+
+        String shareTitleName = IntentUtils.safeGetString(
+                shareTargetMetaData, WebApkMetaDataKeys.SHARE_PARAM_TITLE);
+        if (shareTitleName != null && shareData.subject != null) {
+            postData.add(shareTitleName, ApiCompatibilityUtils.getBytesUtf8(shareData.subject), "",
+                    "text/plain");
         }
-        return computeUrlEncodedPostData(shareTargetMetaData, shareData);
+
+        String shareTextName =
+                IntentUtils.safeGetString(shareTargetMetaData, WebApkMetaDataKeys.SHARE_PARAM_TEXT);
+        if (shareTextName != null && shareData.text != null) {
+            postData.add(shareTextName, ApiCompatibilityUtils.getBytesUtf8(shareData.text), "",
+                    "text/plain");
+        }
+
+        if (!postData.isMultipartEncoding) {
+            return postData;
+        }
+
+        addFilesToMultipartPostData(postData,
+                IntentUtils.safeGetString(
+                        shareTargetMetaData, WebApkMetaDataKeys.SHARE_PARAM_NAMES),
+                IntentUtils.safeGetString(
+                        shareTargetMetaData, WebApkMetaDataKeys.SHARE_PARAM_ACCEPTS),
+                shareData.files);
+
+        return postData;
     }
 }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 834170c..3e9703b 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -373,6 +373,9 @@
       <message name="IDS_SIGN_OUT_AND_TURN_OFF_SYNC" desc="The text for a preferences row that for signs out the user and turns off sync.">
         Sign out and turn off sync
       </message>
+      <message name="IDS_MANAGE_YOUR_GOOGLE_ACCOUNT" desc="Title for link to Google Account Page to manage account settings.">
+        Manage your Google Account
+      </message>
       <message name="IDS_SYNC_CATEGORY_TITLE" desc="Title for the group of Sync-related entries in Settings. This group contains preferences for data tied to user's Google Account.">
         Sync
       </message>
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 8a6f548..745b6ce4 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
@@ -2983,20 +2983,14 @@
                 mActivityTestRule.getActivity().getActivityTab(), testUrl);
     }
 
-    /**
-     * Tests that the flow for showing a dictionary definition works, and that tapping in the
-     * bar just opens the panel instead of taking some action.
-     */
-    @Test
-    @SmallTest
-    @Feature({"ContextualSearch"})
-    public void testDictionaryDefinition() throws InterruptedException, TimeoutException {
+    private void runDictionaryCardTest(@CardTag int cardTag)
+            throws InterruptedException, TimeoutException {
         // Simulate a tap to show the Bar, then set the quick action data.
         simulateTapSearch("search");
         TestThreadUtils.runOnUiThreadBlocking(
                 ()
                         -> mPanel.onSearchTermResolved("obscure · əbˈskyo͝or", null, null,
-                                QuickActionCategory.NONE, CardTag.CT_DEFINITION));
+                                QuickActionCategory.NONE, cardTag));
 
         // Tap on the main portion of the bar.
         clickPanelBar();
@@ -3006,6 +3000,19 @@
     }
 
     /**
+     * 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 testDictionaryDefinitions() throws InterruptedException, TimeoutException {
+        runDictionaryCardTest(CardTag.CT_DEFINITION);
+        closePanel();
+        runDictionaryCardTest(CardTag.CT_CONTEXTUAL_DEFINITION);
+    }
+
+    /**
      * Tests accessibility mode: Tap and Long-press don't activate CS.
      */
     @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java
index 5894f2f..f0bdc81d 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java
@@ -128,9 +128,8 @@
             }
         })
                 .when(mPrefetchBackgroundTask)
-                .nativeStartPrefetchTask(any(), eq(GCM_TOKEN));
+                .nativeStartPrefetchTask(eq(GCM_TOKEN));
         doReturn(true).when(mPrefetchBackgroundTask).nativeOnStopTask(1);
-        doReturn(null).when(mPrefetchBackgroundTask).getProfile();
 
         mFakeTaskScheduler = new FakeBackgroundTaskScheduler();
         BackgroundTaskSchedulerFactory.setSchedulerForTesting(mFakeTaskScheduler);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtilTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtilTest.java
index acbf637..cdbc86e 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtilTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtilTest.java
@@ -43,6 +43,44 @@
                 WEBAPK_PACKAGE_NAME, appBundle, new Bundle[] {shareTargetBundle});
     }
 
+    private static Intent createBasicShareIntent() {
+        Intent intent = new Intent();
+        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WEBAPK_PACKAGE_NAME);
+        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME,
+                WebApkTestHelper.getGeneratedShareTargetActivityClassName(0));
+        intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL);
+        return intent;
+    }
+
+    private static void assertPostData(WebApkShareTargetUtil.PostData postData, String[] names,
+            String[] values, String[] fileNames, String[] types) {
+        Assert.assertNotNull(postData);
+
+        Assert.assertNotNull(postData.names);
+        Assert.assertEquals(postData.names.size(), names.length);
+        for (int i = 0; i < names.length; i++) {
+            Assert.assertEquals(postData.names.get(i), names[i]);
+        }
+
+        Assert.assertNotNull(postData.values);
+        Assert.assertEquals(postData.values.size(), values.length);
+        for (int i = 0; i < values.length; i++) {
+            Assert.assertEquals(new String(postData.values.get(i)), values[i]);
+        }
+
+        Assert.assertNotNull(postData.filenames);
+        Assert.assertEquals(postData.filenames.size(), fileNames.length);
+        for (int i = 0; i < fileNames.length; i++) {
+            Assert.assertEquals(postData.filenames.get(i), fileNames[i]);
+        }
+
+        Assert.assertNotNull(postData.types);
+        Assert.assertEquals(postData.types.size(), types.length);
+        for (int i = 0; i < types.length; i++) {
+            Assert.assertEquals(postData.types.get(i), types[i]);
+        }
+    }
+
     @Implements(WebApkShareTargetUtil.class)
     public static class WebApkShareTargetUtilShadow extends WebApkShareTargetUtil {
         @Implementation
@@ -72,12 +110,7 @@
                 WebApkMetaDataKeys.SHARE_ENCTYPE, "application/x-www-form-urlencoded");
         registerWebApk(shareActivityBundle);
 
-        Intent intent = new Intent();
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WEBAPK_PACKAGE_NAME);
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME,
-                WebApkTestHelper.getGeneratedShareTargetActivityClassName(0));
-        intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL);
-
+        Intent intent = createBasicShareIntent();
         WebApkInfo info = WebApkInfo.create(intent);
 
         Assert.assertEquals(null,
@@ -103,28 +136,17 @@
                 WebApkMetaDataKeys.SHARE_ENCTYPE, "application/x-www-form-urlencoded");
         registerWebApk(shareActivityBundle);
 
-        Intent intent = new Intent();
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WEBAPK_PACKAGE_NAME);
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME,
-                WebApkTestHelper.getGeneratedShareTargetActivityClassName(0));
-        intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL);
+        Intent intent = createBasicShareIntent();
         intent.putExtra(Intent.EXTRA_SUBJECT, "extra_subject");
         intent.putExtra(Intent.EXTRA_TEXT, "extra_text");
         WebApkInfo info = WebApkInfo.create(intent);
 
         WebApkShareTargetUtilShadow.PostData postData =
                 WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData());
-        Assert.assertNotEquals(null, postData);
-        Assert.assertEquals(2, postData.names.length);
-        Assert.assertEquals(2, postData.values.length);
-        Assert.assertEquals(0, postData.filenames.length);
-        Assert.assertEquals(0, postData.types.length);
-        Assert.assertFalse(postData.isMultipartEncoding);
 
-        Assert.assertEquals("title", postData.names[0]);
-        Assert.assertEquals("text", postData.names[1]);
-        Assert.assertEquals("extra_subject", new String(postData.values[0], "UTF-8"));
-        Assert.assertEquals("extra_text", new String(postData.values[1], "UTF-8"));
+        assertPostData(postData, new String[] {"title", "text"},
+                new String[] {"extra_subject", "extra_text"}, new String[] {"", ""},
+                new String[] {"text/plain", "text/plain"});
     }
 
     /**
@@ -138,28 +160,26 @@
         // Note that names and accepts are not specified
         registerWebApk(shareActivityBundle);
 
-        Intent intent = new Intent();
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WEBAPK_PACKAGE_NAME);
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME,
-                WebApkTestHelper.getGeneratedShareTargetActivityClassName(0));
-        intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL);
-
+        Intent intent = createBasicShareIntent();
         ArrayList<Uri> uris = new ArrayList<>();
         uris.add(null);
         intent.putExtra(Intent.EXTRA_STREAM, uris);
 
         WebApkInfo info = WebApkInfo.create(intent);
 
-        Assert.assertEquals(null,
-                WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData()));
+        WebApkShareTargetUtilShadow.PostData postData =
+                WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData());
+
+        assertPostData(
+                postData, new String[] {}, new String[] {}, new String[] {}, new String[] {});
     }
 
     /**
-     * Test that multipart/form-data with no files specified in Intent.EXTRA_STREAM will output a
-     * null postdata.
+     * Test that multipart/form-data with no files or text specified in Intent.EXTRA_STREAM will
+     * output a null postdata.
      */
     @Test
-    public void testPostMultipartWithNoFiles() {
+    public void testPostMultipartWithNoFilesNorText() {
         Bundle shareActivityBundle = new Bundle();
         shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_METHOD, "POST");
         shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_ENCTYPE, "multipart/form-data");
@@ -167,16 +187,15 @@
         shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_ACCEPTS, "[[\"image/*\"]]");
         registerWebApk(shareActivityBundle);
 
-        Intent intent = new Intent();
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WEBAPK_PACKAGE_NAME);
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME,
-                WebApkTestHelper.getGeneratedShareTargetActivityClassName(0));
-        intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL);
+        Intent intent = createBasicShareIntent();
         // Intent.EXTRA_STREAM is not specified.
         WebApkInfo info = WebApkInfo.create(intent);
 
-        Assert.assertEquals(null,
-                WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData()));
+        WebApkShareTargetUtilShadow.PostData postData =
+                WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData());
+
+        assertPostData(
+                postData, new String[] {}, new String[] {}, new String[] {}, new String[] {});
     }
 
     @Test
@@ -188,11 +207,90 @@
         shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_ACCEPTS, "[[\"image/*\"]]");
         registerWebApk(shareActivityBundle);
 
-        Intent intent = new Intent();
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WEBAPK_PACKAGE_NAME);
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME,
-                WebApkTestHelper.getGeneratedShareTargetActivityClassName(0));
-        intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL);
+        Intent intent = createBasicShareIntent();
+        ArrayList<Uri> uris = new ArrayList<>();
+        uris.add(null);
+        intent.putExtra(Intent.EXTRA_STREAM, uris);
+
+        WebApkInfo info = WebApkInfo.create(intent);
+
+        WebApkShareTargetUtilShadow.PostData postData =
+                WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData());
+
+        assertPostData(postData, new String[] {"name"}, new String[] {"content"},
+                new String[] {"filename"}, new String[] {"image/gif"});
+    }
+
+    @Test
+    public void testPostMultipartWithTexts() {
+        Bundle shareActivityBundle = new Bundle();
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_METHOD, "POST");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_ENCTYPE, "multipart/form-data");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_NAMES, "[\"name\"]");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_ACCEPTS, "[[\"image/*\"]]");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_TEXT, "share-text");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_TITLE, "share-title");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_URL, "share-url");
+
+        registerWebApk(shareActivityBundle);
+
+        Intent intent = createBasicShareIntent();
+        intent.putExtra(Intent.EXTRA_SUBJECT, "shared_subject_value");
+        intent.putExtra(Intent.EXTRA_TEXT, "shared_text_value");
+
+        WebApkInfo info = WebApkInfo.create(intent);
+
+        WebApkShareTargetUtilShadow.PostData postData =
+                WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData());
+
+        assertPostData(postData, new String[] {"share-title", "share-text"},
+                new String[] {"shared_subject_value", "shared_text_value"}, new String[] {"", ""},
+                new String[] {"text/plain", "text/plain"});
+    }
+
+    @Test
+    public void testPostMultipartWithTextsOnlyTarget() {
+        Bundle shareActivityBundle = new Bundle();
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_METHOD, "POST");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_ENCTYPE, "multipart/form-data");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_NAMES, "[]");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_ACCEPTS, "[]");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_TEXT, "share-text");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_TITLE, "share-title");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_URL, "share-url");
+
+        registerWebApk(shareActivityBundle);
+
+        Intent intent = createBasicShareIntent();
+        intent.putExtra(Intent.EXTRA_SUBJECT, "shared_subject_value");
+        intent.putExtra(Intent.EXTRA_TEXT, "shared_text_value");
+
+        WebApkInfo info = WebApkInfo.create(intent);
+
+        WebApkShareTargetUtilShadow.PostData postData =
+                WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData());
+
+        assertPostData(postData, new String[] {"share-title", "share-text"},
+                new String[] {"shared_subject_value", "shared_text_value"}, new String[] {"", ""},
+                new String[] {"text/plain", "text/plain"});
+    }
+
+    @Test
+    public void testPostMultipartWithFileAndTexts() {
+        Bundle shareActivityBundle = new Bundle();
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_METHOD, "POST");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_ENCTYPE, "multipart/form-data");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_NAMES, "[\"name\"]");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_ACCEPTS, "[[\"image/*\"]]");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_TEXT, "share-text");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_TITLE, "share-title");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_URL, "share-url");
+
+        registerWebApk(shareActivityBundle);
+
+        Intent intent = createBasicShareIntent();
+        intent.putExtra(Intent.EXTRA_SUBJECT, "shared_subject_value");
+        intent.putExtra(Intent.EXTRA_TEXT, "shared_text_value");
 
         ArrayList<Uri> uris = new ArrayList<>();
         uris.add(null);
@@ -202,18 +300,42 @@
 
         WebApkShareTargetUtilShadow.PostData postData =
                 WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData());
-        Assert.assertNotEquals(null, postData);
 
-        Assert.assertEquals(1, postData.names.length);
-        Assert.assertEquals("name", postData.names[0]);
+        assertPostData(postData, new String[] {"share-title", "share-text", "name"},
+                new String[] {"shared_subject_value", "shared_text_value", "content"},
+                new String[] {"", "", "filename"},
+                new String[] {"text/plain", "text/plain", "image/gif"});
+    }
 
-        Assert.assertEquals(1, postData.values.length);
-        Assert.assertEquals("content", new String(postData.values[0]));
+    @Test
+    public void testPostMultipartWithFileAndInValidParamNames() {
+        Bundle shareActivityBundle = new Bundle();
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_METHOD, "POST");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_ENCTYPE, "multipart/form-data");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_NAMES, "not a array");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_ACCEPTS, "[[\"image/*\"]]");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_TEXT, "share-text");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_TITLE, "share-title");
+        shareActivityBundle.putString(WebApkMetaDataKeys.SHARE_PARAM_URL, "share-url");
 
-        Assert.assertEquals(1, postData.filenames.length);
-        Assert.assertEquals("filename", postData.filenames[0]);
+        registerWebApk(shareActivityBundle);
 
-        Assert.assertEquals(1, postData.types.length);
-        Assert.assertEquals("image/gif", postData.types[0]);
+        Intent intent = createBasicShareIntent();
+        intent.putExtra(Intent.EXTRA_SUBJECT, "shared_subject_value");
+        intent.putExtra(Intent.EXTRA_TEXT, "shared_text_value");
+
+        ArrayList<Uri> uris = new ArrayList<>();
+        uris.add(null);
+        intent.putExtra(Intent.EXTRA_STREAM, uris);
+
+        WebApkInfo info = WebApkInfo.create(intent);
+
+        WebApkShareTargetUtilShadow.PostData postData =
+                WebApkShareTargetUtilShadow.computePostData(WEBAPK_PACKAGE_NAME, info.shareData());
+
+        // with invalid name parameter from Android manifest, we ignore the file sharing part.
+        assertPostData(postData, new String[] {"share-title", "share-text"},
+                new String[] {"shared_subject_value", "shared_text_value"}, new String[] {"", ""},
+                new String[] {"text/plain", "text/plain"});
     }
 }
diff --git a/chrome/android/webapk/shell_apk/AndroidManifest.xml b/chrome/android/webapk/shell_apk/AndroidManifest.xml
index b280718..5415361 100644
--- a/chrome/android/webapk/shell_apk/AndroidManifest.xml
+++ b/chrome/android/webapk/shell_apk/AndroidManifest.xml
@@ -83,13 +83,13 @@
                   android:targetActivity="org.chromium.webapk.shell_apk.[[#use_new_splash]]h2o.H2O[[/use_new_splash]]TransparentLauncherActivity">
           <meta-data android:name="org.chromium.webapk.shell_apk.shareAction" android:value="{{{action}}}" />
           <meta-data android:name="org.chromium.webapk.shell_apk.shareMethod" android:value="{{{method}}}" />
+          <meta-data android:name="org.chromium.webapk.shell_apk.shareParamTitle" android:value="{{{param_title}}}" />
+          <meta-data android:name="org.chromium.webapk.shell_apk.shareParamText" android:value="{{{param_text}}}" />
+          <meta-data android:name="org.chromium.webapk.shell_apk.shareParamUrl" android:value="{{{param_url}}}" />
           {{#enctype}}
           <meta-data android:name="org.chromium.webapk.shell_apk.shareEnctype" android:value="{{{enctype}}}" />
           {{/enctype}}
           {{^is_file_upload}}
-          <meta-data android:name="org.chromium.webapk.shell_apk.shareParamTitle" android:value="{{{param_title}}}" />
-          <meta-data android:name="org.chromium.webapk.shell_apk.shareParamText" android:value="{{{param_text}}}" />
-          <meta-data android:name="org.chromium.webapk.shell_apk.shareParamUrl" android:value="{{{param_url}}}" />
           <intent-filter>
             <action android:name="android.intent.action.SEND" />
             <category android:name="android.intent.category.DEFAULT" />
@@ -97,11 +97,15 @@
           </intent-filter>
           {{/is_file_upload}}
           {{#is_file_upload}}
+          {{^is_file_upload_param_empty}}
           <meta-data android:name="org.chromium.webapk.shell_apk.shareParamNames" android:value="{{{param_names}}}" />
           <meta-data android:name="org.chromium.webapk.shell_apk.shareParamAccepts" android:value="{{{param_accepts}}}" />
+          {{/is_file_upload_param_empty}}
           <intent-filter>
             <action android:name="android.intent.action.SEND" />
+            {{^is_file_upload_param_empty}}
             <action android:name="android.intent.action.SEND_MULTIPLE" />
+            {{/is_file_upload_param_empty}}
             <category android:name="android.intent.category.DEFAULT" />
             {{#mime_types}}
             <data android:mimeType="{{{mime_type}}}" />
diff --git a/chrome/app/chrome_packaged_service_manifests.cc b/chrome/app/chrome_packaged_service_manifests.cc
index 02b3b793..af654fb 100644
--- a/chrome/app/chrome_packaged_service_manifests.cc
+++ b/chrome/app/chrome_packaged_service_manifests.cc
@@ -119,6 +119,7 @@
                                    InstanceSharingPolicy::kSingleton)
                            .Build())
           .RequireCapability("network", "network_service")
+          .RequireCapability("device", "device:wake_lock")
           .Build()};
   return *manifest;
 }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index ba45101..733b7f7 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4812,8 +4812,6 @@
       "supervised_user/child_accounts/kids_management_api.h",
       "supervised_user/child_accounts/permission_request_creator_apiary.cc",
       "supervised_user/child_accounts/permission_request_creator_apiary.h",
-      "supervised_user/experimental/safe_search_url_reporter.cc",
-      "supervised_user/experimental/safe_search_url_reporter.h",
       "supervised_user/experimental/supervised_user_blacklist.cc",
       "supervised_user/experimental/supervised_user_blacklist.h",
       "supervised_user/experimental/supervised_user_filtering_switches.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 85878a4..a30d3813 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1204,6 +1204,9 @@
     {"enable-webassembly-code-gc", flag_descriptions::kEnableWasmCodeGCName,
      flag_descriptions::kEnableWasmCodeGCDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kWebAssemblyCodeGC)},
+    {"enable-webassembly-simd", flag_descriptions::kEnableWasmSimdName,
+     flag_descriptions::kEnableWasmSimdDescription, kOsAll,
+     FEATURE_VALUE_TYPE(features::kWebAssemblySimd)},
     {"enable-webassembly-threads", flag_descriptions::kEnableWasmThreadsName,
      flag_descriptions::kEnableWasmThreadsDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kWebAssemblyThreads)},
@@ -1955,10 +1958,6 @@
      flag_descriptions::kAutofillCreditCardUploadDescription, kOsAll,
      FEATURE_VALUE_TYPE(autofill::features::kAutofillUpstream)},
 #endif  // TOOLKIT_VIEWS || OS_ANDROID
-    {"safe-search-url-reporting",
-     flag_descriptions::kSafeSearchUrlReportingName,
-     flag_descriptions::kSafeSearchUrlReportingDescription, kOsAll,
-     FEATURE_VALUE_TYPE(features::kSafeSearchUrlReporting)},
     {"force-ui-direction", flag_descriptions::kForceUiDirectionName,
      flag_descriptions::kForceUiDirectionDescription, kOsAll,
      MULTI_VALUE_TYPE(kForceUIDirectionChoices)},
@@ -2454,6 +2453,10 @@
      flag_descriptions::kOmniboxReverseTabSwitchLogicName,
      flag_descriptions::kOmniboxReverseTabSwitchLogicDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(omnibox::kOmniboxReverseTabSwitchLogic)},
+    {"omnibox-short-bookmark-suggestions",
+     flag_descriptions::kOmniboxShortBookmarkSuggestionsName,
+     flag_descriptions::kOmniboxShortBookmarkSuggestionsDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(omnibox::kOmniboxShortBookmarkSuggestions)},
     {"omnibox-tail-suggestions", flag_descriptions::kOmniboxTailSuggestionsName,
      flag_descriptions::kOmniboxTailSuggestionsDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(omnibox::kOmniboxTailSuggestions)},
diff --git a/chrome/browser/android/download/download_manager_service.cc b/chrome/browser/android/download/download_manager_service.cc
index 7fab0bf4..4567806 100644
--- a/chrome/browser/android/download/download_manager_service.cc
+++ b/chrome/browser/android/download/download_manager_service.cc
@@ -33,6 +33,7 @@
 #include "components/download/public/common/download_item_impl.h"
 #include "components/download/public/common/download_url_loader_factory_getter_impl.h"
 #include "components/download/public/common/simple_download_manager_coordinator.h"
+#include "components/download/public/common/url_download_handler_factory.h"
 #include "components/download/public/task/task_manager_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/download_item_utils.h"
@@ -248,6 +249,9 @@
     content::BrowserContext* context) {
   if (in_progress_manager_) {
     DCHECK(!context->IsOffTheRecord());
+    // We are no longer interested in listening to |in_progress_manager_|,
+    // remove this object from being the delegate.
+    in_progress_manager_->SetDelegate(nullptr);
     // Set |is_pending_downloads_loaded_| to false so that we need to wait for
     // download history to initialize before performing new download actions.
     is_pending_downloads_loaded_ = false;
@@ -693,7 +697,7 @@
   base::FilePath data_dir;
   base::android::GetDataDirectory(&data_dir);
   in_progress_manager_ = std::make_unique<download::InProgressDownloadManager>(
-      nullptr, data_dir.Append(chrome::kInitialProfile),
+      this, data_dir.Append(chrome::kInitialProfile),
       base::BindRepeating(&IgnoreOriginSecurityCheck),
       base::BindRepeating(&content::DownloadRequestUtils::IsURLSafe));
   content::GetNetworkServiceFromConnector(service_binding_.GetConnector());
@@ -704,7 +708,6 @@
           factory->Clone()));
   in_progress_manager_->set_download_start_observer(
       DownloadControllerBase::Get());
-  in_progress_manager_->SetDelegate(this);
 }
 
 void DownloadManagerService::OnPendingDownloadsLoaded() {
@@ -752,12 +755,17 @@
 }
 
 void DownloadManagerService::OnDownloadsInitialized() {
-  // We are no longer interested in listening to |in_progress_manager_|, remove
-  // this object from being the delegate.
-  in_progress_manager_->SetDelegate(nullptr);
   OnPendingDownloadsLoaded();
 }
 
+std::unique_ptr<service_manager::Connector>
+DownloadManagerService::GetServiceConnector() {
+  service_manager::Connector* connector = service_binding_.GetConnector();
+  if (connector)
+    return connector->Clone();  // Clone for use on a different thread.
+  return nullptr;
+}
+
 content::DownloadManager* DownloadManagerService::GetDownloadManager(
     bool is_off_the_record) {
   Profile* profile = ProfileManager::GetActiveUserProfile();
diff --git a/chrome/browser/android/download/download_manager_service.h b/chrome/browser/android/download/download_manager_service.h
index 9bb8fca..547fd5b 100644
--- a/chrome/browser/android/download/download_manager_service.h
+++ b/chrome/browser/android/download/download_manager_service.h
@@ -239,6 +239,7 @@
 
   // download::InProgressDownloadManager::Delegate implementations.
   void OnDownloadsInitialized() override;
+  std::unique_ptr<service_manager::Connector> GetServiceConnector() override;
 
   typedef base::Callback<void(bool)> ResumeCallback;
   void set_resume_callback_for_testing(const ResumeCallback& resume_cb) {
diff --git a/chrome/browser/android/webapk/webapk_post_share_target_navigator.cc b/chrome/browser/android/webapk/webapk_post_share_target_navigator.cc
index 33ee5cf8..2293081 100644
--- a/chrome/browser/android/webapk/webapk_post_share_target_navigator.cc
+++ b/chrome/browser/android/webapk/webapk_post_share_target_navigator.cc
@@ -54,10 +54,16 @@
   }
 
   std::string body;
-  for (size_t i = 0; i < num_files; i++)
-    net::AddMultipartValueForUploadWithFileName(
-        PercentEscapeString(names[i]), PercentEscapeString(filenames[i]),
-        values[i], boundary, types[i], &body);
+  for (size_t i = 0; i < num_files; i++) {
+    if (filenames[i].empty()) {
+      net::AddMultipartValueForUpload(PercentEscapeString(names[i]), values[i],
+                                      boundary, types[i], &body);
+    } else {
+      net::AddMultipartValueForUploadWithFileName(
+          PercentEscapeString(names[i]), PercentEscapeString(filenames[i]),
+          values[i], boundary, types[i], &body);
+    }
+  }
   net::AddMultipartFinalDelimiterForUpload(boundary, &body);
   return body;
 }
diff --git a/chrome/browser/android/webapk/webapk_post_share_target_navigator_unittest.cc b/chrome/browser/android/webapk/webapk_post_share_target_navigator_unittest.cc
index 8b2b8410..10cca58 100644
--- a/chrome/browser/android/webapk/webapk_post_share_target_navigator_unittest.cc
+++ b/chrome/browser/android/webapk/webapk_post_share_target_navigator_unittest.cc
@@ -20,8 +20,9 @@
   EXPECT_EQ("", multipart_body);
 }
 
-// Test that multipart/form-data body is correctly computed for accepted inputs.
-TEST(WebApkActivityTest, ValidMultipartBody) {
+// Test that multipart/form-data body is correctly computed for accepted
+// file inputs.
+TEST(WebApkActivityTest, ValidMultipartBodyForFile) {
   std::vector<std::string> names = {"name\""};
   std::vector<std::string> values = {"value"};
   std::vector<std::string> filenames = {"filename\r\n"};
@@ -37,6 +38,44 @@
   EXPECT_EQ(expected_multipart_body, multipart_body);
 }
 
+// Test that multipart/form-data body is correctly computed for non-file inputs.
+TEST(WebApkActivityTest, ValidMultipartBodyForText) {
+  std::vector<std::string> names = {"name\""};
+  std::vector<std::string> values = {"value"};
+  std::vector<std::string> filenames = {""};
+  std::vector<std::string> types = {"type"};
+  std::string boundary = "boundary";
+  std::string multipart_body =
+      webapk::ComputeMultipartBody(names, values, filenames, types, boundary);
+  std::string expected_multipart_body =
+      "--boundary\r\nContent-Disposition: form-data;"
+      " name=\"name%22\"\r\nContent-Type: type"
+      "\r\n\r\nvalue\r\n"
+      "--boundary--\r\n";
+  EXPECT_EQ(expected_multipart_body, multipart_body);
+}
+
+// Test that multipart/form-data body is correctly computed for a mixture
+// of file and non-file inputs.
+TEST(WebApkActivityTest, ValidMultipartBodyForTextAndFile) {
+  std::vector<std::string> names = {"name1\"", "name2"};
+  std::vector<std::string> values = {"value1", "value2"};
+  std::vector<std::string> filenames = {"", "filename2\r\n"};
+  std::vector<std::string> types = {"type1", "type2"};
+  std::string boundary = "boundary";
+  std::string multipart_body =
+      webapk::ComputeMultipartBody(names, values, filenames, types, boundary);
+  std::string expected_multipart_body =
+      "--boundary\r\nContent-Disposition: form-data;"
+      " name=\"name1%22\"\r\nContent-Type: type1"
+      "\r\n\r\nvalue1\r\n"
+      "--boundary\r\nContent-Disposition: form-data;"
+      " name=\"name2\"; filename=\"filename2%0D%0A\"\r\nContent-Type: type2"
+      "\r\n\r\nvalue2\r\n"
+      "--boundary--\r\n";
+  EXPECT_EQ(expected_multipart_body, multipart_body);
+}
+
 // Test that multipart/form-data body is properly percent-escaped.
 TEST(WebApkActivityTest, MultipartBodyWithPercentEncoding) {
   std::vector<std::string> names = {"name"};
diff --git a/chrome/browser/background_fetch/background_fetch_permission_context.cc b/chrome/browser/background_fetch/background_fetch_permission_context.cc
index 686a060..0061b5e 100644
--- a/chrome/browser/background_fetch/background_fetch_permission_context.cc
+++ b/chrome/browser/background_fetch/background_fetch_permission_context.cc
@@ -68,7 +68,7 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   // The user should never be prompted to authorize Background Fetch
   // from BackgroundFetchPermissionContext.
   // BackgroundFetchDelegateImpl invokes CanDownload() on DownloadRequestLimiter
@@ -80,7 +80,7 @@
     const PermissionRequestID& id,
     const GURL& requesting_origin,
     const GURL& embedding_origin,
-    const BrowserPermissionCallback& callback,
+    BrowserPermissionCallback callback,
     bool persist,
     ContentSetting content_setting) {
   DCHECK(!persist);
diff --git a/chrome/browser/background_fetch/background_fetch_permission_context.h b/chrome/browser/background_fetch/background_fetch_permission_context.h
index 3e484fe..37efe17 100644
--- a/chrome/browser/background_fetch/background_fetch_permission_context.h
+++ b/chrome/browser/background_fetch/background_fetch_permission_context.h
@@ -33,11 +33,11 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
   void NotifyPermissionSet(const PermissionRequestID& id,
                            const GURL& requesting_origin,
                            const GURL& embedding_origin,
-                           const BrowserPermissionCallback& callback,
+                           BrowserPermissionCallback callback,
                            bool persist,
                            ContentSetting content_setting) override;
 
diff --git a/chrome/browser/background_sync/background_sync_permission_context.cc b/chrome/browser/background_sync/background_sync_permission_context.cc
index 180f006..821f8b7 100644
--- a/chrome/browser/background_sync/background_sync_permission_context.cc
+++ b/chrome/browser/background_sync/background_sync_permission_context.cc
@@ -19,7 +19,7 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   // The user should never be prompted to authorize background sync.
   NOTREACHED();
 }
diff --git a/chrome/browser/background_sync/background_sync_permission_context.h b/chrome/browser/background_sync/background_sync_permission_context.h
index 65268e0..e2ed7ef 100644
--- a/chrome/browser/background_sync/background_sync_permission_context.h
+++ b/chrome/browser/background_sync/background_sync_permission_context.h
@@ -29,7 +29,7 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
   bool IsRestrictedToSecureOrigins() const override;
 
   DISALLOW_COPY_AND_ASSIGN(BackgroundSyncPermissionContext);
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context.cc b/chrome/browser/background_sync/periodic_background_sync_permission_context.cc
index 167bab4..dda667d 100644
--- a/chrome/browser/background_sync/periodic_background_sync_permission_context.cc
+++ b/chrome/browser/background_sync/periodic_background_sync_permission_context.cc
@@ -4,8 +4,12 @@
 
 #include "chrome/browser/background_sync/periodic_background_sync_permission_context.h"
 
+#include "build/build_config.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/extensions/extension_util.h"
+#include "chrome/browser/profiles/profile.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_features.h"
 
@@ -15,6 +19,16 @@
                             CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC,
                             blink::mojom::FeaturePolicyFeature::kNotFound) {}
 
+bool PeriodicBackgroundSyncPermissionContext::IsPwaInstalled(
+    const GURL& url) const {
+#if defined(OS_ANDROID)
+  // TODO(crbug.com/925297): Add logic to detect PWAs on Android.
+  return false;
+#else
+  return extensions::util::GetInstalledPwaForUrl(profile(), url);
+#endif
+}
+
 bool PeriodicBackgroundSyncPermissionContext::IsRestrictedToSecureOrigins()
     const {
   return true;
@@ -30,15 +44,25 @@
   if (!base::FeatureList::IsEnabled(features::kPeriodicBackgroundSync))
     return CONTENT_SETTING_BLOCK;
 
-  // TODO(crbug.com/925297): Add PWA detection logic, and restrict the feature
-  // to origins with a PWA installed.
+  // TODO(crbug.com/925297): If there's a TWA installed for the origin, grant
+  // permission.
 
+  if (!IsPwaInstalled(requesting_origin))
+    return CONTENT_SETTING_BLOCK;
+
+  // PWA installed. Check for one-shot Background Sync content setting.
+  // Expected values are CONTENT_SETTING_BLOCK or CONTENT_SETTING_ALLOW.
   auto* host_content_settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile());
   DCHECK(host_content_settings_map);
 
-  return PermissionContextBase::GetPermissionStatusInternal(
-      render_frame_host, requesting_origin, embedding_origin);
+  auto content_setting = host_content_settings_map->GetContentSetting(
+      requesting_origin, embedding_origin,
+      CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC,
+      /* resource_identifier= */ std::string());
+  DCHECK(content_setting == CONTENT_SETTING_BLOCK ||
+         content_setting == CONTENT_SETTING_ALLOW);
+  return content_setting;
 }
 
 void PeriodicBackgroundSyncPermissionContext::DecidePermission(
@@ -47,7 +71,7 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   // The user should never be prompted to authorize Periodic Background Sync
   // from PeriodicBackgroundSyncPermissionContext.
   NOTREACHED();
@@ -57,7 +81,7 @@
     const PermissionRequestID& id,
     const GURL& requesting_origin,
     const GURL& embedding_origin,
-    const BrowserPermissionCallback& callback,
+    BrowserPermissionCallback callback,
     bool persist,
     ContentSetting content_setting) {
   DCHECK(!persist);
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context.h b/chrome/browser/background_sync/periodic_background_sync_permission_context.h
index 1bc677b8..1331e0c8 100644
--- a/chrome/browser/background_sync/periodic_background_sync_permission_context.h
+++ b/chrome/browser/background_sync/periodic_background_sync_permission_context.h
@@ -25,6 +25,10 @@
   explicit PeriodicBackgroundSyncPermissionContext(Profile* profile);
   ~PeriodicBackgroundSyncPermissionContext() override = default;
 
+ protected:
+  // Virtual for testing.
+  virtual bool IsPwaInstalled(const GURL& url) const;
+
  private:
   // PermissionContextBase implementation.
   bool IsRestrictedToSecureOrigins() const override;
@@ -37,11 +41,11 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
   void NotifyPermissionSet(const PermissionRequestID& id,
                            const GURL& requesting_origin,
                            const GURL& embedding_origin,
-                           const BrowserPermissionCallback& callback,
+                           BrowserPermissionCallback callback,
                            bool persist,
                            ContentSetting content_setting) override;
 
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc b/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
index 4bec21971..e060c4d 100644
--- a/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
+++ b/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/macros.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/common/web_application_info.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -21,16 +22,43 @@
 
 namespace {
 
+class TestPeriodicBackgroundSyncPermissionContext
+    : public PeriodicBackgroundSyncPermissionContext {
+ public:
+  explicit TestPeriodicBackgroundSyncPermissionContext(Profile* profile)
+      : PeriodicBackgroundSyncPermissionContext(profile) {}
+
+  void InstallPwa(const GURL& url) { installed_pwas_.insert(url); }
+
+  // PeriodicBackgroundSyncPermissionContext overrides:
+  bool IsPwaInstalled(const GURL& url) const override {
+    return installed_pwas_.find(url) != installed_pwas_.end();
+  }
+
+ private:
+  std::set<GURL> installed_pwas_;
+};
+
 class PeriodicBackgroundSyncPermissionContextTest
     : public ChromeRenderViewHostTestHarness {
  protected:
   PeriodicBackgroundSyncPermissionContextTest() = default;
   ~PeriodicBackgroundSyncPermissionContextTest() override = default;
 
-  ContentSetting GetPermissionStatus(
-      const GURL& url,
-      PeriodicBackgroundSyncPermissionContext* permission_context,
-      bool with_frame) {
+  void SetUp() override {
+    ChromeRenderViewHostTestHarness::SetUp();
+    permission_context_ =
+        std::make_unique<TestPeriodicBackgroundSyncPermissionContext>(
+            profile());
+  }
+
+  void TearDown() override {
+    // The destructor for |permission_context_| needs a valid thread bundle.
+    permission_context_.reset();
+    ChromeRenderViewHostTestHarness::TearDown();
+  }
+
+  ContentSetting GetPermissionStatus(const GURL& url, bool with_frame = false) {
     content::RenderFrameHost* render_frame_host = nullptr;
 
     if (with_frame) {
@@ -38,74 +66,82 @@
       render_frame_host = web_contents()->GetMainFrame();
     }
 
-    auto permission_result = permission_context->GetPermissionStatus(
+    auto permission_result = permission_context_->GetPermissionStatus(
         render_frame_host, /* requesting_origin= */ url,
         /* embedding_origin= */ url);
     return permission_result.content_setting;
   }
 
-  void SetPeriodicSyncContentSetting(const GURL& url, ContentSetting setting) {
+  void SetBackgroundSyncContentSetting(const GURL& url,
+                                       ContentSetting setting) {
     auto* host_content_settings_map =
         HostContentSettingsMapFactory::GetForProfile(profile());
     ASSERT_TRUE(host_content_settings_map);
     host_content_settings_map->SetContentSettingDefaultScope(
         /* primary_url= */ url, /* secondary_url= */ url,
-        CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC,
+        CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC,
         /* resource_identifier= */ std::string(), setting);
   }
 
+  void InstallPwa(const GURL& url) { permission_context_->InstallPwa(url); }
+
+  void SetUpPwaAndContentSettings(const GURL& url) {
+    InstallPwa(url);
+    SetBackgroundSyncContentSetting(url, CONTENT_SETTING_ALLOW);
+  }
+
  private:
+  std::unique_ptr<TestPeriodicBackgroundSyncPermissionContext>
+      permission_context_;
   DISALLOW_COPY_AND_ASSIGN(PeriodicBackgroundSyncPermissionContextTest);
 };
 
 TEST_F(PeriodicBackgroundSyncPermissionContextTest, DenyWhenFeatureDisabled) {
-  PeriodicBackgroundSyncPermissionContext permission_context(profile());
-
-  GURL url("https://example.com");
-  EXPECT_EQ(GetPermissionStatus(url, &permission_context,
-                                /* with_frame= */ true),
+  EXPECT_EQ(GetPermissionStatus(GURL("https://example.com")),
             CONTENT_SETTING_BLOCK);
 }
 
 TEST_F(PeriodicBackgroundSyncPermissionContextTest, DenyForInsecureOrigin) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync);
-
-  PeriodicBackgroundSyncPermissionContext permission_context(profile());
-
   GURL url("http://example.com");
-  SetPeriodicSyncContentSetting(url, CONTENT_SETTING_ALLOW);
-  EXPECT_EQ(GetPermissionStatus(url, &permission_context,
-                                /* with_frame= */ false),
+  SetBackgroundSyncContentSetting(url, CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(GetPermissionStatus(url, /* with_frame= */ false),
             CONTENT_SETTING_BLOCK);
 }
 
 TEST_F(PeriodicBackgroundSyncPermissionContextTest, AllowWithFrame) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync);
-
   GURL url("https://example.com");
-  SetPeriodicSyncContentSetting(url, CONTENT_SETTING_ALLOW);
+  SetUpPwaAndContentSettings(url);
+  SetBackgroundSyncContentSetting(url, CONTENT_SETTING_ALLOW);
 
-  PeriodicBackgroundSyncPermissionContext permission_context(profile());
-
-  EXPECT_EQ(GetPermissionStatus(url, &permission_context,
-                                /* with_frame= */ true),
+  EXPECT_EQ(GetPermissionStatus(url, /* with_frame= */ true),
             CONTENT_SETTING_ALLOW);
 }
 
 TEST_F(PeriodicBackgroundSyncPermissionContextTest, AllowWithoutFrame) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync);
-
   GURL url("https://example.com");
-  SetPeriodicSyncContentSetting(url, CONTENT_SETTING_ALLOW);
+  SetUpPwaAndContentSettings(url);
 
-  PeriodicBackgroundSyncPermissionContext permission_context(profile());
-
-  EXPECT_EQ(GetPermissionStatus(url, &permission_context,
-                                /* with_frame= */ false),
+  EXPECT_EQ(GetPermissionStatus(url, /* with_frame= */ false),
             CONTENT_SETTING_ALLOW);
 }
 
+TEST_F(PeriodicBackgroundSyncPermissionContextTest, DesktopPWA) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync);
+  GURL url("https://example.com");
+  SetUpPwaAndContentSettings(url);
+
+  EXPECT_EQ(GetPermissionStatus(url), CONTENT_SETTING_ALLOW);
+
+  // Disable one-shot Background Sync.
+  SetBackgroundSyncContentSetting(url, CONTENT_SETTING_BLOCK);
+  EXPECT_EQ(GetPermissionStatus(url), CONTENT_SETTING_BLOCK);
+}
+
 }  // namespace
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 1c5b0bf3..22172ab 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -76,6 +76,7 @@
 #include "chrome/browser/metrics/renderer_uptime_tracker.h"
 #include "chrome/browser/metrics/thread_watcher.h"
 #include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
+#include "chrome/browser/net/system_network_context_manager.h"
 #include "chrome/browser/performance_monitor/process_monitor.h"
 #include "chrome/browser/performance_monitor/system_monitor.h"
 #include "chrome/browser/plugins/plugin_prefs.h"
@@ -1311,17 +1312,6 @@
   // running.
   browser_process_->PreMainMessageLoopRun();
 
-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
-  // Wait for the result of machine level user cloud policy enrollment after
-  // we start the enrollment process in browser_porcess_->PreMainMessageLoopRun.
-  // Abort the launch process if the enrollment is failed.
-  if (!browser_process_->browser_policy_connector()
-           ->machine_level_user_cloud_policy_controller()
-           ->WaitUntilPolicyEnrollmentFinished()) {
-    return chrome::RESULT_CODE_CLOUD_POLICY_ENROLLMENT_FAILED;
-  }
-#endif
-
   // Record last shutdown time into a histogram.
   browser_shutdown::ReadLastShutdownInfo();
 
@@ -1416,6 +1406,32 @@
       return chrome::RESULT_CODE_PROFILE_IN_USE;
   }
 
+#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
+  // Initialize the machine level user cloud policy controller after the
+  // browser process singleton is acquired to remove race conditions where
+  // multiple browser processes start simultaneously.  The main
+  // initialization of browser_policy_connector is performed inside
+  // PreMainMessageLoopRun() so that policies can be applied as soon as
+  // possible.
+  //
+  // Note that this protects against multiple browser process starts in
+  // the same user data dir and not multiple starts across user data dirs.
+  browser_process_->browser_policy_connector()
+      ->machine_level_user_cloud_policy_controller()
+      ->Init(browser_process_->local_state(),
+             browser_process_->system_network_context_manager()
+                 ->GetSharedURLLoaderFactory());
+
+  // Wait for the machine level user cloud policy enrollment to finish.
+  // If no enrollment is needed, this function returns immediately.
+  // Abort the launch process if the enrollment fails.
+  if (!browser_process_->browser_policy_connector()
+           ->machine_level_user_cloud_policy_controller()
+           ->WaitUntilPolicyEnrollmentFinished()) {
+    return chrome::RESULT_CODE_CLOUD_POLICY_ENROLLMENT_FAILED;
+  }
+#endif
+
   // Handle special early return paths (which couldn't be processed even earlier
   // as they require the process singleton to be held) first.
 
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 85b2d5e..d0673c7c 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -2277,6 +2277,7 @@
     "arc/process/arc_process_unittest.cc",
     "arc/tracing/arc_cpu_event_unittest.cc",
     "arc/tracing/arc_graphics_jank_detector_unittest.cc",
+    "arc/tracing/arc_system_model_unittest.cc",
     "arc/tracing/arc_system_stat_collector_unittest.cc",
     "arc/tracing/arc_tracing_model_unittest.cc",
     "arc/tracing/arc_value_event_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_model.cc b/chrome/browser/chromeos/arc/tracing/arc_system_model.cc
index f5cb611..38061164 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_system_model.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_system_model.cc
@@ -60,6 +60,11 @@
   return result;
 }
 
+template <typename T>
+bool CompareByTimestampPred(const T& a, const T& b) {
+  return a.timestamp < b.timestamp;
+}
+
 }  // namespace
 
 ArcSystemModel::ThreadInfo::ThreadInfo() = default;
@@ -81,6 +86,54 @@
   memory_events_.clear();
 }
 
+void ArcSystemModel::Trim(int64_t trim_timestamp) {
+  const ArcCpuEvent cpu_trim_point(
+      trim_timestamp, ArcCpuEvent::Type::kActive /* does not matter */,
+      0 /* tid, does not matter */);
+  for (auto& cpu_events : all_cpu_events_) {
+    if (cpu_events.empty())
+      continue;
+    auto cpu_cut_pos =
+        std::lower_bound(cpu_events.begin(), cpu_events.end(), cpu_trim_point,
+                         CompareByTimestampPred<ArcCpuEvent>);
+    if (cpu_cut_pos == cpu_events.begin())
+      continue;  // Nothing to trim.
+    // Keep the last message for this CPU, that would be clamped to
+    // |trim_timestamp|.
+    if (cpu_cut_pos == cpu_events.end() ||
+        cpu_cut_pos->timestamp != trim_timestamp) {
+      --cpu_cut_pos;
+      cpu_cut_pos->timestamp = trim_timestamp;
+    }
+    cpu_events = CpuEvents(cpu_cut_pos, cpu_events.end());
+  }
+
+  const ArcValueEvent memory_trim_point(
+      trim_timestamp, ArcValueEvent::Type::kMemTotal /* does not matter */,
+      0 /* value, does not matter */);
+  auto memory_cut_pos = std::upper_bound(
+      memory_events_.begin(), memory_events_.end(), memory_trim_point,
+      CompareByTimestampPred<ArcValueEvent>);
+
+  // Keep the last message per type, that would be trimmed to |trim_timestamp|.
+  ValueEvents trimmed_memory_events;
+  std::set<ArcValueEvent::Type> trimmed_types;
+  auto scan_memory = memory_cut_pos;
+  while (scan_memory != memory_events_.begin()) {
+    --scan_memory;
+    if (!trimmed_types.count(scan_memory->type)) {
+      ArcValueEvent memory_event = *scan_memory;
+      memory_event.timestamp = trim_timestamp;
+      trimmed_memory_events.insert(trimmed_memory_events.begin(), memory_event);
+      trimmed_types.insert(memory_event.type);
+    }
+  }
+  // Add the rest after the trim point.
+  trimmed_memory_events.insert(trimmed_memory_events.end(), memory_cut_pos,
+                               memory_events_.end());
+  memory_events_ = std::move(trimmed_memory_events);
+}
+
 void ArcSystemModel::CopyFrom(const ArcSystemModel& other) {
   thread_map_ = other.thread_map_;
   all_cpu_events_ = other.all_cpu_events_;
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_model.h b/chrome/browser/chromeos/arc/tracing/arc_system_model.h
index 94f6567..c2a4aea 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_system_model.h
+++ b/chrome/browser/chromeos/arc/tracing/arc_system_model.h
@@ -38,6 +38,11 @@
   ~ArcSystemModel();
 
   void Reset();
+  // Trims the model using |trim_timestamp|. Events before
+  // |trim_timestamp| are consolidated with their timestamps aligned
+  // to |trim_timestamp|. Events on or after |trim_timestamp| are left
+  // in the model unchanged.
+  void Trim(int64_t trim_timestamp);
 
   void CopyFrom(const ArcSystemModel& other);
   base::DictionaryValue Serialize() const;
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_model_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_system_model_unittest.cc
new file mode 100644
index 0000000..6d7951d
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_system_model_unittest.cc
@@ -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.
+
+#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+
+using ArcSystemModelTest = testing::Test;
+
+TEST_F(ArcSystemModelTest, TrimByTimestampCPU) {
+  ArcSystemModel model;
+
+  constexpr int64_t trim_timestamp = 25;
+  constexpr int idle_tid = 0;
+  constexpr int non_idle_tid = 100;
+
+  // Second event is before |trim_timestamp|. First event should be discard,
+  // second should be preserved but with clamped timestamp to |trim_timestamp|.
+  AddAllCpuEvent(&model.all_cpu_events(), 0 /* cpu_id */, 10 /* timestamp */,
+                 ArcCpuEvent::Type::kIdleIn, idle_tid);
+  AddAllCpuEvent(&model.all_cpu_events(), 0 /* cpu_id */, 20 /* timestamp */,
+                 ArcCpuEvent::Type::kWakeUp, non_idle_tid);
+  AddAllCpuEvent(&model.all_cpu_events(), 0 /* cpu_id */, 30 /* timestamp */,
+                 ArcCpuEvent::Type::kIdleOut, idle_tid);
+
+  // All events are after |trim_timestamp|. Everything should be preserved.
+  AddAllCpuEvent(&model.all_cpu_events(), 1 /* cpu_id */, 32 /* timestamp */,
+                 ArcCpuEvent::Type::kIdleIn, idle_tid);
+  AddAllCpuEvent(&model.all_cpu_events(), 1 /* cpu_id */, 42 /* timestamp */,
+                 ArcCpuEvent::Type::kWakeUp, non_idle_tid);
+  AddAllCpuEvent(&model.all_cpu_events(), 1 /* cpu_id */, 52 /* timestamp */,
+                 ArcCpuEvent::Type::kIdleOut, idle_tid);
+
+  // Second event is exactly |on trim_timestamp|. First even should be
+  // discarded.
+  AddAllCpuEvent(&model.all_cpu_events(), 2 /* cpu_id */, 15 /* timestamp */,
+                 ArcCpuEvent::Type::kIdleIn, idle_tid);
+  AddAllCpuEvent(&model.all_cpu_events(), 2 /* cpu_id */, 25 /* timestamp */,
+                 ArcCpuEvent::Type::kWakeUp, non_idle_tid);
+  AddAllCpuEvent(&model.all_cpu_events(), 2 /* cpu_id */, 35 /* timestamp */,
+                 ArcCpuEvent::Type::kIdleOut, idle_tid);
+
+  // All events are before |trim_timestamp|. Last one should be preserved but
+  // with clamped timestamp to |trim_timestamp|.
+  AddAllCpuEvent(&model.all_cpu_events(), 3 /* cpu_id */, 10 /* timestamp */,
+                 ArcCpuEvent::Type::kIdleIn, idle_tid);
+  AddAllCpuEvent(&model.all_cpu_events(), 3 /* cpu_id */, 15 /* timestamp */,
+                 ArcCpuEvent::Type::kWakeUp, non_idle_tid);
+  AddAllCpuEvent(&model.all_cpu_events(), 3 /* cpu_id */, 20 /* timestamp */,
+                 ArcCpuEvent::Type::kIdleOut, idle_tid);
+
+  model.Trim(trim_timestamp);
+
+  ASSERT_EQ(4U, model.all_cpu_events().size());
+  const CpuEvents& cpu_events_0 = model.all_cpu_events()[0 /* cpu_id */];
+  const CpuEvents& cpu_events_1 = model.all_cpu_events()[1 /* cpu_id */];
+  const CpuEvents& cpu_events_2 = model.all_cpu_events()[2 /* cpu_id */];
+  const CpuEvents& cpu_events_3 = model.all_cpu_events()[3 /* cpu_id */];
+
+  ASSERT_EQ(2U, cpu_events_0.size());
+  EXPECT_EQ(ArcCpuEvent::Type::kWakeUp, cpu_events_0[0].type);
+  EXPECT_EQ(trim_timestamp, cpu_events_0[0].timestamp);
+
+  ASSERT_EQ(3U, cpu_events_1.size());
+  EXPECT_EQ(ArcCpuEvent::Type::kIdleIn, cpu_events_1[0].type);
+  EXPECT_EQ(32, cpu_events_1[0].timestamp);
+
+  ASSERT_EQ(2U, cpu_events_2.size());
+  EXPECT_EQ(ArcCpuEvent::Type::kWakeUp, cpu_events_2[0].type);
+  EXPECT_EQ(trim_timestamp, cpu_events_2[0].timestamp);
+
+  ASSERT_EQ(1U, cpu_events_3.size());
+  EXPECT_EQ(ArcCpuEvent::Type::kIdleOut, cpu_events_3[0].type);
+  EXPECT_EQ(trim_timestamp, cpu_events_3[0].timestamp);
+}
+
+TEST_F(ArcSystemModelTest, TrimByTimestampMemory) {
+  ArcSystemModel model;
+
+  constexpr int64_t trim_timestamp = 25;
+
+  // First of ArcValueEvent::Type::kMemTotal should be clamped to
+  // |trim_timestamp|.
+  model.memory_events().emplace_back(
+      0 /* timestamp */, ArcValueEvent::Type::kMemTotal, 100 /* value */);
+  model.memory_events().emplace_back(
+      0 /* timestamp */, ArcValueEvent::Type::kMemUsed, 20 /* value */);
+  model.memory_events().emplace_back(
+      0 /* timestamp */, ArcValueEvent::Type::kSwapRead, 0 /* value */);
+
+  model.memory_events().emplace_back(
+      10 /* timestamp */, ArcValueEvent::Type::kSwapRead, 1 /* value */);
+
+  model.memory_events().emplace_back(
+      20 /* timestamp */, ArcValueEvent::Type::kSwapRead, 2 /* value */);
+
+  // Second of |ArcValueEvent::Type::kMemUsed| is exactly on |trim_timestamp|.
+  // First |ArcValueEvent::Type::kMemUsed| should be discarded.
+  model.memory_events().emplace_back(
+      25 /* timestamp */, ArcValueEvent::Type::kMemUsed, 30 /* value */);
+
+  // We have 3 |ArcValueEvent::Type::kSwapRead| before. Two first should be
+  // discarded and third one should be clamped to |trim_timestamp|.
+  model.memory_events().emplace_back(
+      30 /* timestamp */, ArcValueEvent::Type::kSwapRead, 3 /* value */);
+
+  model.memory_events().emplace_back(
+      40 /* timestamp */, ArcValueEvent::Type::kSwapRead, 4 /* value */);
+
+  model.memory_events().emplace_back(
+      50 /* timestamp */, ArcValueEvent::Type::kMemTotal, 100 /* value */);
+  model.memory_events().emplace_back(
+      50 /* timestamp */, ArcValueEvent::Type::kMemUsed, 40 /* value */);
+  model.memory_events().emplace_back(
+      50 /* timestamp */, ArcValueEvent::Type::kSwapRead, 5 /* value */);
+
+  EXPECT_EQ(11u, model.memory_events().size());
+
+  model.Trim(trim_timestamp);
+
+  ASSERT_EQ(8u, model.memory_events().size());
+  EXPECT_EQ(ArcValueEvent(trim_timestamp, ArcValueEvent::Type::kMemTotal, 100),
+            model.memory_events()[0]);
+  EXPECT_EQ(ArcValueEvent(trim_timestamp, ArcValueEvent::Type::kSwapRead, 2),
+            model.memory_events()[1]);
+  EXPECT_EQ(ArcValueEvent(trim_timestamp, ArcValueEvent::Type::kMemUsed, 30),
+            model.memory_events()[2]);
+
+  EXPECT_EQ(ArcValueEvent(30, ArcValueEvent::Type::kSwapRead, 3),
+            model.memory_events()[3]);
+  EXPECT_EQ(ArcValueEvent(40, ArcValueEvent::Type::kSwapRead, 4),
+            model.memory_events()[4]);
+
+  EXPECT_EQ(ArcValueEvent(50, ArcValueEvent::Type::kMemTotal, 100),
+            model.memory_events()[5]);
+  EXPECT_EQ(ArcValueEvent(50, ArcValueEvent::Type::kMemUsed, 40),
+            model.memory_events()[6]);
+  EXPECT_EQ(ArcValueEvent(50, ArcValueEvent::Type::kSwapRead, 5),
+            model.memory_events()[7]);
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
index 654c545..ea30156 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
@@ -997,6 +997,34 @@
 
 ArcTracingGraphicsModel::~ArcTracingGraphicsModel() = default;
 
+// static
+void ArcTracingGraphicsModel::TrimEventsContainer(
+    ArcTracingGraphicsModel::EventsContainer* container,
+    int64_t trim_timestamp,
+    const std::set<ArcTracingGraphicsModel::BufferEventType>& start_types) {
+  const ArcTracingGraphicsModel::BufferEvent trim_point(
+      ArcTracingGraphicsModel::BufferEventType::kCustomEvent, trim_timestamp);
+
+  // Global events are trimmed by timestamp only.
+  auto global_cut_pos = std::lower_bound(container->global_events().begin(),
+                                         container->global_events().end(),
+                                         trim_point, SortByTimestampPred);
+  container->global_events() = ArcTracingGraphicsModel::BufferEvents(
+      global_cut_pos, container->global_events().end());
+
+  for (auto& buffer : container->buffer_events()) {
+    auto cut_pos = std::lower_bound(buffer.begin(), buffer.end(), trim_point,
+                                    SortByTimestampPred);
+    while (cut_pos != buffer.end()) {
+      if (start_types.count(cut_pos->type))
+        break;
+      ++cut_pos;
+    }
+
+    buffer = ArcTracingGraphicsModel::BufferEvents(cut_pos, buffer.end());
+  }
+}
+
 bool ArcTracingGraphicsModel::Build(const ArcTracingModel& common_model) {
   Reset();
 
@@ -1095,6 +1123,8 @@
 
   system_model_.CopyFrom(common_model.system_model());
 
+  VsyncTrim();
+
   NormalizeTimestamps();
 
   return true;
@@ -1162,6 +1192,35 @@
   duration_ = 0;
 }
 
+void ArcTracingGraphicsModel::VsyncTrim() {
+  int64_t trim_timestamp = -1;
+
+  for (const auto& it : android_top_level_.global_events()) {
+    if (it.type == BufferEventType::kVsync) {
+      trim_timestamp = it.timestamp;
+      break;
+    }
+  }
+
+  if (trim_timestamp < 0) {
+    LOG(ERROR) << "VSYNC event was not found, could not trim.";
+    return;
+  }
+
+  TrimEventsContainer(&chrome_top_level_, trim_timestamp,
+                      {BufferEventType::kChromeOSDraw});
+  TrimEventsContainer(&android_top_level_, trim_timestamp,
+                      {BufferEventType::kSurfaceFlingerInvalidationStart,
+                       BufferEventType::kSurfaceFlingerCompositionStart});
+  for (auto& view_buffer : view_buffers_) {
+    TrimEventsContainer(&view_buffer.second, trim_timestamp,
+                        {BufferEventType::kBufferQueueDequeueStart,
+                         BufferEventType::kExoSurfaceAttach,
+                         BufferEventType::kChromeBarrierOrder});
+  }
+  system_model_.Trim(trim_timestamp);
+}
+
 int ArcTracingGraphicsModel::GetTaskIdFromBufferName(
     const std::string& chrome_buffer_name) const {
   const auto it = chrome_buffer_id_to_task_id_.find(chrome_buffer_name);
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h
index 4b08249..e17c34c7 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h
@@ -138,6 +138,15 @@
   ArcTracingGraphicsModel();
   ~ArcTracingGraphicsModel();
 
+  // Trims container events by |trim_timestamp|. All global events are discarded
+  // prior to |trim_timestamp|. Buffer events are discarded prior to
+  // |trim_timestamp| and on and after until event from |start_types| is
+  // detected.
+  static void TrimEventsContainer(
+      ArcTracingGraphicsModel::EventsContainer* container,
+      int64_t trim_timestamp,
+      const std::set<ArcTracingGraphicsModel::BufferEventType>& start_types);
+
   // Builds the model from the common tracing model |common_model|.
   bool Build(const ArcTracingModel& common_model);
 
@@ -172,6 +181,11 @@
   // Resets whole model.
   void Reset();
 
+  // Trims events before first VSYNC event. ARC tracing starts delayed in
+  // comparison with Chrome, memory and CPU events. That makes empty area for
+  // graphics buffer confusing.
+  void VsyncTrim();
+
   // Extracts task id from the Chrome buffer name. Returns -1 if task id cannot
   // be extracted.
   int GetTaskIdFromBufferName(const std::string& chrome_buffer_name) const;
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc
index 9e8e0880..543e077 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc
@@ -186,6 +186,12 @@
       graphics_model.android_top_level().global_events(),
       {GraphicsEventType::kVsync,
        GraphicsEventType::kSurfaceFlingerCompositionJank}));
+  ASSERT_FALSE(graphics_model.android_top_level().global_events().empty());
+  // Check trimmed by VSYNC.
+  EXPECT_EQ(GraphicsEventType::kVsync,
+            graphics_model.android_top_level().global_events()[0].type);
+  EXPECT_EQ(0, graphics_model.android_top_level().global_events()[0].timestamp);
+
   EXPECT_EQ(2U, graphics_model.chrome_top_level().buffer_events().size());
   for (const auto& chrome_top_level_band :
        graphics_model.chrome_top_level().buffer_events()) {
@@ -225,14 +231,15 @@
   }
 
   // Note, CPU events in |graphics_model| are normalized by timestamp. So they
-  // are not equal and we cannot do direct comparison.
-  ASSERT_EQ(graphics_model.system_model().all_cpu_events().size(),
+  // are not equal and we cannot do direct comparison. Also first VSYNC event
+  // trimming may drop some events.
+  ASSERT_LE(graphics_model.system_model().all_cpu_events().size(),
             model.system_model().all_cpu_events().size());
   EXPECT_EQ(graphics_model.system_model().thread_map(),
             model.system_model().thread_map());
   for (size_t i = 0; i < graphics_model.system_model().all_cpu_events().size();
        ++i) {
-    EXPECT_EQ(graphics_model.system_model().all_cpu_events()[i].size(),
+    EXPECT_LE(graphics_model.system_model().all_cpu_events()[i].size(),
               model.system_model().all_cpu_events()[i].size());
   }
 
@@ -427,4 +434,46 @@
   EXPECT_FALSE(LoadGraphicsModel("gm_bad_wrong_timestamp.json"));
 }
 
+TEST_F(ArcTracingModelTest, EventsContainerTrim) {
+  ArcTracingGraphicsModel::EventsContainer events;
+  constexpr int64_t trim_timestamp = 25;
+  events.global_events().emplace_back(
+      ArcTracingGraphicsModel::BufferEventType::kChromeOSJank,
+      15 /* timestamp */);
+  events.global_events().emplace_back(
+      ArcTracingGraphicsModel::BufferEventType::kChromeOSJank,
+      25 /* timestamp */);
+  events.global_events().emplace_back(
+      ArcTracingGraphicsModel::BufferEventType::kChromeOSJank,
+      30 /* timestamp */);
+  events.global_events().emplace_back(
+      ArcTracingGraphicsModel::BufferEventType::kChromeOSJank,
+      35 /* timestamp */);
+  events.buffer_events().resize(1);
+  // Two sequences, first sequence starts before trim and ends after. After
+  // trimming  next sequence should be preserved only.
+  events.buffer_events()[0].emplace_back(
+      ArcTracingGraphicsModel::BufferEventType::kChromeOSDraw,
+      20 /* timestamp */);
+  events.buffer_events()[0].emplace_back(
+      ArcTracingGraphicsModel::BufferEventType::kChromeOSSwapDone,
+      30 /* timestamp */);
+  events.buffer_events()[0].emplace_back(
+      ArcTracingGraphicsModel::BufferEventType::kChromeOSDraw,
+      40 /* timestamp */);
+  events.buffer_events()[0].emplace_back(
+      ArcTracingGraphicsModel::BufferEventType::kChromeOSSwapDone,
+      50 /* timestamp */);
+  ArcTracingGraphicsModel::TrimEventsContainer(
+      &events, trim_timestamp,
+      {ArcTracingGraphicsModel::BufferEventType::kChromeOSDraw});
+  ASSERT_EQ(3U, events.global_events().size());
+  EXPECT_EQ(25, events.global_events()[0].timestamp);
+  ASSERT_EQ(1U, events.buffer_events().size());
+  ASSERT_EQ(2U, events.buffer_events()[0].size());
+  EXPECT_EQ(40, events.buffer_events()[0][0].timestamp);
+  EXPECT_EQ(ArcTracingGraphicsModel::BufferEventType::kChromeOSDraw,
+            events.buffer_events()[0][0].type);
+}
+
 }  // namespace arc
diff --git a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
index 099ddca..3d39a6d 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
+++ b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
@@ -41,7 +41,7 @@
 views::Widget* PlatformVerificationDialog::ShowDialog(
     content::WebContents* web_contents,
     const GURL& requesting_origin,
-    const ConsentCallback& callback) {
+    ConsentCallback callback) {
   // This could happen when the permission is requested from an extension. See
   // http://crbug.com/728534
   // TODO(wittman): Remove this check after ShowWebModalDialogViews() API is
@@ -64,9 +64,7 @@
   std::string origin = extension ? extension->name() : requesting_origin.spec();
 
   PlatformVerificationDialog* dialog = new PlatformVerificationDialog(
-      web_contents,
-      base::UTF8ToUTF16(origin),
-      callback);
+      web_contents, base::UTF8ToUTF16(origin), std::move(callback));
 
   return constrained_window::ShowWebModalDialogViews(dialog, web_contents);
 }
@@ -77,10 +75,10 @@
 PlatformVerificationDialog::PlatformVerificationDialog(
     content::WebContents* web_contents,
     const base::string16& domain,
-    const ConsentCallback& callback)
+    ConsentCallback callback)
     : content::WebContentsObserver(web_contents),
       domain_(domain),
-      callback_(callback),
+      callback_(std::move(callback)),
       learn_more_button_(nullptr) {
   SetLayoutManager(std::make_unique<views::FillLayout>());
   SetBorder(views::CreateEmptyBorder(
@@ -109,13 +107,13 @@
 
 bool PlatformVerificationDialog::Cancel() {
   // This method is called when user clicked "Block" button.
-  callback_.Run(CONSENT_RESPONSE_DENY);
+  std::move(callback_).Run(CONSENT_RESPONSE_DENY);
   return true;
 }
 
 bool PlatformVerificationDialog::Accept() {
   // This method is called when user clicked "Allow" button.
-  callback_.Run(CONSENT_RESPONSE_ALLOW);
+  std::move(callback_).Run(CONSENT_RESPONSE_ALLOW);
   return true;
 }
 
@@ -123,7 +121,7 @@
   // This method is called when user clicked "x" or pressed "Esc" to dismiss the
   // dialog, the permission request is canceled, or when the tab containing this
   // dialog is closed.
-  callback_.Run(CONSENT_RESPONSE_NONE);
+  std::move(callback_).Run(CONSENT_RESPONSE_NONE);
   return true;
 }
 
diff --git a/chrome/browser/chromeos/attestation/platform_verification_dialog.h b/chrome/browser/chromeos/attestation/platform_verification_dialog.h
index ebeda20e..9fcdc393 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_dialog.h
+++ b/chrome/browser/chromeos/attestation/platform_verification_dialog.h
@@ -31,15 +31,16 @@
     CONSENT_RESPONSE_DENY
   };
 
-  using ConsentCallback = base::Callback<void(ConsentResponse response)>;
+  using ConsentCallback = base::OnceCallback<void(ConsentResponse response)>;
 
   // Initializes a tab-modal dialog for |web_contents| and |requesting_origin|
   // and shows it. Returns a non-owning pointer to the widget so that caller can
   // close the dialog and cancel the request. The returned widget is only
-  // guaranteed to be valid before |callback| is called.
+  // guaranteed to be valid before |callback| is called. The |callback| will
+  // never be run when null is returned.
   static views::Widget* ShowDialog(content::WebContents* web_contents,
                                    const GURL& requesting_origin,
-                                   const ConsentCallback& callback);
+                                   ConsentCallback callback);
 
  protected:
   ~PlatformVerificationDialog() override;
@@ -47,7 +48,7 @@
  private:
   PlatformVerificationDialog(content::WebContents* web_contents,
                              const base::string16& domain,
-                             const ConsentCallback& callback);
+                             ConsentCallback callback);
 
   // views::DialogDelegate:
   View* CreateExtraView() override;
diff --git a/chrome/browser/complex_tasks/task_tab_helper.cc b/chrome/browser/complex_tasks/task_tab_helper.cc
index aac07fc4..3b047fe 100644
--- a/chrome/browser/complex_tasks/task_tab_helper.cc
+++ b/chrome/browser/complex_tasks/task_tab_helper.cc
@@ -9,11 +9,20 @@
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "components/search_engines/template_url_service.h"
+#include "components/sessions/content/content_record_task_id.h"
 #include "content/public/browser/navigation_entry.h"
 
+#if defined(OS_ANDROID)
+#include "chrome/browser/android/tab_android.h"
+#include "jni/TaskTabHelper_jni.h"
+
+using base::android::JavaParamRef;
+#endif  // defined(OS_ANDROID)
+
 namespace tasks {
 
 TaskTabHelper::TaskTabHelper(content::WebContents* web_contents)
@@ -69,6 +78,21 @@
       entry_index_to_spoke_count_map_[current_entry_index]);
 }
 
+sessions::ContextRecordTaskId* TaskTabHelper::GetContextRecordTaskId(
+    content::WebContents* web_contents) {
+  if (!web_contents)
+    return nullptr;
+  content::NavigationEntry* navigation_entry =
+      web_contents->GetController().GetLastCommittedEntry();
+  if (!navigation_entry)
+    return nullptr;
+  sessions::ContextRecordTaskId* context_record_task_id =
+      sessions::ContextRecordTaskId::Get(navigation_entry);
+  if (!context_record_task_id)
+    return nullptr;
+  return context_record_task_id;
+}
+
 void TaskTabHelper::RecordHubAndSpokeNavigationUsage(int spokes) {
   DCHECK_GT(spokes, 1);
 
@@ -95,6 +119,43 @@
   base::UmaHistogramExactLinear(histogram_name, spokes, 100);
 }
 
+#if defined(OS_ANDROID)
+int64_t TaskTabHelper::GetParentTaskId() {
+  TabAndroid* tab_android = TabAndroid::FromWebContents(web_contents());
+  return Java_TaskTabHelper_getParentTaskId(
+      base::android::AttachCurrentThread(), tab_android->GetJavaObject());
+}
+
+int64_t TaskTabHelper::GetParentRootTaskId() {
+  TabAndroid* tab_android = TabAndroid::FromWebContents(web_contents());
+  return Java_TaskTabHelper_getParentRootTaskId(
+      base::android::AttachCurrentThread(), tab_android->GetJavaObject());
+}
+
+jlong JNI_TaskTabHelper_GetTaskId(JNIEnv* env,
+                                  const JavaParamRef<jobject>& jweb_contents) {
+  sessions::ContextRecordTaskId* context_record_task_id =
+      TaskTabHelper::GetContextRecordTaskId(
+          content::WebContents::FromJavaWebContents(jweb_contents));
+  if (context_record_task_id) {
+    return context_record_task_id->task_id();
+  }
+  return -1;
+}
+
+jlong JNI_TaskTabHelper_GetRootTaskId(
+    JNIEnv* env,
+    const JavaParamRef<jobject>& jweb_contents) {
+  sessions::ContextRecordTaskId* context_record_task_id =
+      TaskTabHelper::GetContextRecordTaskId(
+          content::WebContents::FromJavaWebContents(jweb_contents));
+  if (context_record_task_id) {
+    return context_record_task_id->root_task_id();
+  }
+  return -1;
+}
+#endif  // defined(OS_ANDROID)
+
 WEB_CONTENTS_USER_DATA_KEY_IMPL(TaskTabHelper)
 
 }  // namespace tasks
diff --git a/chrome/browser/complex_tasks/task_tab_helper.h b/chrome/browser/complex_tasks/task_tab_helper.h
index c681148e..999fa9b 100644
--- a/chrome/browser/complex_tasks/task_tab_helper.h
+++ b/chrome/browser/complex_tasks/task_tab_helper.h
@@ -8,10 +8,15 @@
 #include <map>
 
 #include "base/macros.h"
+#include "build/build_config.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
+namespace sessions {
+class ContextRecordTaskId;
+}
+
 namespace tasks {
 
 // This is a tab helper that collects navigation state information of a
@@ -26,6 +31,8 @@
       const content::LoadCommittedDetails& load_details) override;
   void NavigationListPruned(
       const content::PrunedDetails& pruned_details) override;
+  static sessions::ContextRecordTaskId* GetContextRecordTaskId(
+      content::WebContents* web_contents);
 
  protected:
   explicit TaskTabHelper(content::WebContents* web_contents);
@@ -44,6 +51,11 @@
 
   void RecordHubAndSpokeNavigationUsage(int sample);
 
+#if defined(OS_ANDROID)
+  int64_t GetParentTaskId();
+  int64_t GetParentRootTaskId();
+#endif  // defined(OS_ANDROID)
+
   int last_pruned_navigation_entry_index_;
   std::map<int, int> entry_index_to_spoke_count_map_;
 
diff --git a/chrome/browser/complex_tasks/task_tab_helper_unittest.cc b/chrome/browser/complex_tasks/task_tab_helper_unittest.cc
index 5f56efc..c3c233e8 100644
--- a/chrome/browser/complex_tasks/task_tab_helper_unittest.cc
+++ b/chrome/browser/complex_tasks/task_tab_helper_unittest.cc
@@ -8,7 +8,9 @@
 
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/sessions/content/content_record_task_id.h"
 #include "content/public/test/navigation_simulator.h"
+#include "content/public/test/web_contents_tester.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -174,3 +176,27 @@
   EXPECT_THAT(histogram_tester_.GetAllSamples(from_form_submit_histogram),
               testing::ElementsAre(base::Bucket(2, 1)));
 }
+
+TEST_F(TaskTabHelperUnitTest, TestGetContextRecordTaskId) {
+  std::unique_ptr<content::WebContents> test_parent_web_contents(
+      content::WebContentsTester::CreateTestWebContents(
+          web_contents()->GetBrowserContext(), nullptr));
+  GURL parent_gurl("http://parent.com");
+  content::WebContentsTester::For(test_parent_web_contents.get())
+      ->NavigateAndCommit(parent_gurl);
+
+  content::NavigationEntry* navigation_entry =
+      test_parent_web_contents->GetController().GetLastCommittedEntry();
+  sessions::ContextRecordTaskId* context_record_task_id =
+      sessions::ContextRecordTaskId::Get(navigation_entry);
+  context_record_task_id->set_task_id(3);
+  context_record_task_id->set_root_task_id(4);
+  EXPECT_EQ(tasks::TaskTabHelper::GetContextRecordTaskId(
+                test_parent_web_contents.get())
+                ->task_id(),
+            3);
+  EXPECT_EQ(tasks::TaskTabHelper::GetContextRecordTaskId(
+                test_parent_web_contents.get())
+                ->root_task_id(),
+            4);
+}
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index 382c1c5..e10c172 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -105,6 +105,7 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/context_menu_params.h"
+#include "content/public/common/service_manager_connection.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/download_test_observer.h"
 #include "content/public/test/slow_download_http_response.h"
@@ -121,6 +122,10 @@
 #include "net/test/embedded_test_server/http_response.h"
 #include "net/test/url_request/url_request_mock_http_job.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/device/public/mojom/constants.mojom.h"
+#include "services/device/public/mojom/wake_lock.mojom.h"
+#include "services/device/public/mojom/wake_lock_provider.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/page_transition_types.h"
@@ -1195,6 +1200,40 @@
   std::unique_ptr<TestSafeBrowsingServiceFactory> test_safe_browsing_factory_;
 };
 
+class DownloadWakeLockTest : public DownloadTest {
+ public:
+  DownloadWakeLockTest() = default;
+
+  void Initialize() {
+    auto* connection = content::ServiceManagerConnection::GetForProcess();
+    auto* connector = connection->GetConnector();
+    connector_ = connector->Clone();
+    connector_->BindInterface(device::mojom::kServiceName,
+                              &wake_lock_provider_);
+  }
+
+  // Returns the number of active wake locks of type |type|.
+  int GetActiveWakeLocks(device::mojom::WakeLockType type) {
+    base::RunLoop run_loop;
+    int result_count = 0;
+    wake_lock_provider_->GetActiveWakeLocksForTests(
+        type,
+        base::BindOnce(
+            [](base::RunLoop* run_loop, int* result_count, int32_t count) {
+              *result_count = count;
+              run_loop->Quit();
+            },
+            &run_loop, &result_count));
+    run_loop.Run();
+    return result_count;
+  }
+
+ protected:
+  device::mojom::WakeLockProviderPtr wake_lock_provider_;
+  std::unique_ptr<service_manager::Connector> connector_;
+  DISALLOW_COPY_AND_ASSIGN(DownloadWakeLockTest);
+};
+
 }  // namespace
 
 // NOTES:
@@ -3707,6 +3746,20 @@
   ASSERT_TRUE(origin_three.ShutdownAndWaitUntilComplete());
 }
 
+IN_PROC_BROWSER_TEST_F(DownloadWakeLockTest, WakeLockAcquireAndCancel) {
+  Initialize();
+  EXPECT_EQ(0, GetActiveWakeLocks(
+                   device::mojom::WakeLockType::kPreventAppSuspension));
+  DownloadItem* download_item = CreateSlowTestDownload();
+  ASSERT_TRUE(download_item);
+  EXPECT_EQ(1, GetActiveWakeLocks(
+                   device::mojom::WakeLockType::kPreventAppSuspension));
+  download_item->Cancel(true);
+  EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
+  EXPECT_EQ(0, GetActiveWakeLocks(
+                   device::mojom::WakeLockType::kPreventAppSuspension));
+}
+
 #if defined(FULL_SAFE_BROWSING)
 
 namespace {
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc
index 884ccbf..323534a7 100644
--- a/chrome/browser/download/download_prefs.cc
+++ b/chrome/browser/download/download_prefs.cc
@@ -160,12 +160,17 @@
       prefs->GetBoolean(prefs::kOpenPdfDownloadInSystemReader);
 #endif
 
-  // If the download path is dangerous we forcefully reset it. But if we do
-  // so we set a flag to make sure we only do it once, to avoid fighting
-  // the user if they really want it on an unsafe place such as the desktop.
-  if (!prefs->GetBoolean(prefs::kDownloadDirUpgraded)) {
-    base::FilePath current_download_dir = prefs->GetFilePath(
-        prefs::kDownloadDefaultDirectory);
+  base::FilePath current_download_dir =
+      prefs->GetFilePath(prefs::kDownloadDefaultDirectory);
+  if (!current_download_dir.IsAbsolute()) {
+    // If we have a relative path or an empty path, we should reset to a safe,
+    // well-known path.
+    prefs->SetFilePath(prefs::kDownloadDefaultDirectory,
+                       GetDefaultDownloadDirectoryForProfile());
+  } else if (!prefs->GetBoolean(prefs::kDownloadDirUpgraded)) {
+    // If the download path is dangerous we forcefully reset it. But if we do
+    // so we set a flag to make sure we only do it once, to avoid fighting
+    // the user if they really want it on an unsafe place such as the desktop.
     if (DownloadPathIsDangerous(current_download_dir)) {
       prefs->SetFilePath(prefs::kDownloadDefaultDirectory,
                          GetDefaultDownloadDirectoryForProfile());
@@ -499,7 +504,14 @@
   // Fall back to the default download directory for all other paths.
   return GetDefaultDownloadDirectoryForProfile();
 #endif
-  return path;
+  // If the stored download directory is an absolute path, we presume it's
+  // correct; there's not really much more validation we can do here.
+  if (path.IsAbsolute())
+    return path;
+
+  // When the default download directory is *not* an absolute path, we use the
+  // profile directory as a safe default.
+  return GetDefaultDownloadDirectoryForProfile();
 }
 
 bool DownloadPrefs::AutoOpenCompareFunctor::operator()(
diff --git a/chrome/browser/download/download_prefs_unittest.cc b/chrome/browser/download/download_prefs_unittest.cc
index a88de72..bcc4f29 100644
--- a/chrome/browser/download/download_prefs_unittest.cc
+++ b/chrome/browser/download/download_prefs_unittest.cc
@@ -128,6 +128,52 @@
       base::FilePath(FILE_PATH_LITERAL("x.Bar"))));
 }
 
+TEST(DownloadPrefsTest, MissingDefaultPathCorrected) {
+  content::TestBrowserThreadBundle threads_are_required_for_testing_profile;
+  TestingProfile profile;
+  profile.GetPrefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
+                                  base::FilePath());
+  EXPECT_FALSE(profile.GetPrefs()
+                   ->GetFilePath(prefs::kDownloadDefaultDirectory)
+                   .IsAbsolute());
+
+  DownloadPrefs download_prefs(&profile);
+  EXPECT_TRUE(download_prefs.DownloadPath().IsAbsolute())
+      << "Default download directory is " << download_prefs.DownloadPath();
+}
+
+TEST(DownloadPrefsTest, RelativeDefaultPathCorrected) {
+  content::TestBrowserThreadBundle threads_are_required_for_testing_profile;
+  TestingProfile profile;
+
+  profile.GetPrefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
+                                  base::FilePath::FromUTF8Unsafe(".."));
+  EXPECT_FALSE(profile.GetPrefs()
+                   ->GetFilePath(prefs::kDownloadDefaultDirectory)
+                   .IsAbsolute());
+
+  DownloadPrefs download_prefs(&profile);
+  EXPECT_TRUE(download_prefs.DownloadPath().IsAbsolute())
+      << "Default download directory is " << download_prefs.DownloadPath();
+}
+
+TEST(DownloadPrefsTest, DefaultPathChangedToInvalidValue) {
+  content::TestBrowserThreadBundle threads_are_required_for_testing_profile;
+  TestingProfile profile;
+  profile.GetPrefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
+                                  profile.GetPath());
+  EXPECT_TRUE(profile.GetPrefs()
+                  ->GetFilePath(prefs::kDownloadDefaultDirectory)
+                  .IsAbsolute());
+
+  DownloadPrefs download_prefs(&profile);
+  EXPECT_TRUE(download_prefs.DownloadPath().IsAbsolute());
+
+  download_prefs.SetDownloadPath(base::FilePath::FromUTF8Unsafe(".."));
+  EXPECT_EQ(download_prefs.DownloadPath(),
+            download_prefs.GetDefaultDownloadDirectory());
+}
+
 #if defined(OS_CHROMEOS)
 void ExpectValidDownloadDir(Profile* profile,
                             DownloadPrefs* prefs,
diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc
index 73e35f8..8a0c1260 100644
--- a/chrome/browser/extensions/extension_management.cc
+++ b/chrome/browser/extensions/extension_management.cc
@@ -107,7 +107,8 @@
 }
 
 bool ExtensionManagement::BlacklistedByDefault() const {
-  return default_settings_->installation_mode == INSTALLATION_BLOCKED;
+  return (default_settings_->installation_mode == INSTALLATION_BLOCKED ||
+          default_settings_->installation_mode == INSTALLATION_REMOVED);
 }
 
 ExtensionManagement::InstallationMode ExtensionManagement::GetInstallationMode(
@@ -139,8 +140,10 @@
 }
 
 bool ExtensionManagement::HasWhitelistedExtension() const {
-  if (default_settings_->installation_mode != INSTALLATION_BLOCKED)
+  if (default_settings_->installation_mode != INSTALLATION_BLOCKED &&
+      default_settings_->installation_mode != INSTALLATION_REMOVED) {
     return true;
+  }
 
   for (const auto& it : settings_by_id_) {
     if (it.second->installation_mode == INSTALLATION_ALLOWED)
diff --git a/chrome/browser/extensions/extension_management.h b/chrome/browser/extensions/extension_management.h
index 7d7fa1a..10394ec 100644
--- a/chrome/browser/extensions/extension_management.h
+++ b/chrome/browser/extensions/extension_management.h
@@ -64,11 +64,14 @@
   //                        and cannot be disabled.
   // * INSTALLATION_RECOMMENDED: Extension will be installed automatically but
   //                             can be disabled.
+  // * INSTALLATION_REMOVED:  Extension cannot be installed and will be
+  //                          automatically removed.
   enum InstallationMode {
     INSTALLATION_ALLOWED = 0,
     INSTALLATION_BLOCKED,
     INSTALLATION_FORCED,
     INSTALLATION_RECOMMENDED,
+    INSTALLATION_REMOVED,
   };
 
   explicit ExtensionManagement(Profile* profile);
diff --git a/chrome/browser/extensions/extension_management_constants.cc b/chrome/browser/extensions/extension_management_constants.cc
index 9cb2f25..c8c73c1 100644
--- a/chrome/browser/extensions/extension_management_constants.cc
+++ b/chrome/browser/extensions/extension_management_constants.cc
@@ -16,6 +16,7 @@
 const char kBlocked[] = "blocked";
 const char kForceInstalled[] = "force_installed";
 const char kNormalInstalled[] = "normal_installed";
+const char kRemoved[] = "removed";
 
 const char kBlockedPermissions[] = "blocked_permissions";
 const char kAllowedPermissions[] = "allowed_permissions";
diff --git a/chrome/browser/extensions/extension_management_constants.h b/chrome/browser/extensions/extension_management_constants.h
index 421e6d2..cb8b081 100644
--- a/chrome/browser/extensions/extension_management_constants.h
+++ b/chrome/browser/extensions/extension_management_constants.h
@@ -21,6 +21,7 @@
 extern const char kBlocked[];
 extern const char kForceInstalled[];
 extern const char kNormalInstalled[];
+extern const char kRemoved[];
 
 extern const char kBlockedPermissions[];
 extern const char kAllowedPermissions[];
diff --git a/chrome/browser/extensions/extension_management_internal.cc b/chrome/browser/extensions/extension_management_internal.cc
index e696eb7..3c8436a5 100644
--- a/chrome/browser/extensions/extension_management_internal.cc
+++ b/chrome/browser/extensions/extension_management_internal.cc
@@ -55,6 +55,8 @@
       installation_mode = ExtensionManagement::INSTALLATION_FORCED;
     } else if (installation_mode_str == schema_constants::kNormalInstalled) {
       installation_mode = ExtensionManagement::INSTALLATION_RECOMMENDED;
+    } else if (installation_mode_str == schema_constants::kRemoved) {
+      installation_mode = ExtensionManagement::INSTALLATION_REMOVED;
     } else {
       // Invalid value for 'installation_mode'.
       LOG(WARNING) << kMalformedPreferenceWarning;
diff --git a/chrome/browser/extensions/standard_management_policy_provider.cc b/chrome/browser/extensions/standard_management_policy_provider.cc
index bf49c50..0fec71b 100644
--- a/chrome/browser/extensions/standard_management_policy_provider.cc
+++ b/chrome/browser/extensions/standard_management_policy_provider.cc
@@ -120,8 +120,10 @@
 
   ExtensionManagement::InstallationMode installation_mode =
       settings_->GetInstallationMode(extension);
-  if (installation_mode == ExtensionManagement::INSTALLATION_BLOCKED)
+  if (installation_mode == ExtensionManagement::INSTALLATION_BLOCKED ||
+      installation_mode == ExtensionManagement::INSTALLATION_REMOVED) {
     return ReturnLoadError(extension, error);
+  }
 
   return true;
 }
@@ -202,12 +204,15 @@
 bool StandardManagementPolicyProvider::ShouldForceUninstall(
     const Extension* extension,
     base::string16* error) const {
-  if (!settings_->ShouldUninstallPolicyBlacklistedExtensions())
-    return false;
   if (UserMayLoad(extension, error))
     return false;
   if (settings_->GetInstallationMode(extension) ==
-      ExtensionManagement::INSTALLATION_BLOCKED) {
+          ExtensionManagement::INSTALLATION_BLOCKED &&
+      settings_->ShouldUninstallPolicyBlacklistedExtensions()) {
+    return true;
+  }
+  if (settings_->GetInstallationMode(extension) ==
+      ExtensionManagement::INSTALLATION_REMOVED) {
     return true;
   }
   return false;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index b83ab02..a29933b 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1857,6 +1857,11 @@
     "expiry_milestone": 80
   },
   {
+    "name": "enable-webassembly-simd",
+    "owners": [ "gdeepti", "wasm-team@google.com" ],
+    "expiry_milestone": 82
+  },
+  {
     "name": "enable-webassembly-threads",
     "owners": [ "binji", "hablich", "wasm-team@google.com" ],
     "expiry_milestone": 76
@@ -2499,6 +2504,11 @@
     "expiry_milestone": 76
   },
   {
+    "name": "omnibox-short-bookmark-suggestions",
+    "owners": [ "krb", "chrome-omnibox-team@google.com" ],
+    "expiry_milestone": 78
+  },
+  {
     "name": "omnibox-spare-renderer",
     "owners": [ "chrome-omnibox-team@google.com" ],
     "expiry_milestone": 76
@@ -2771,11 +2781,6 @@
     "expiry_milestone": 76
   },
   {
-    "name": "safe-search-url-reporting",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
-  },
-  {
     "name": "same-site-by-default-cookies",
     "owners": [ "chlily", "morlovich" ],
     "expiry_milestone": 80
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 13ff4fd..af32327 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -943,6 +943,10 @@
 const char kEnableWasmCodeGCDescription[] =
     "Enables garbage collection of WebAssembly code.";
 
+const char kEnableWasmSimdName[] = "WebAssembly SIMD support.";
+const char kEnableWasmSimdDescription[] =
+    "Enables support for the WebAssembly SIMD proposal.";
+
 const char kEnableWasmThreadsName[] = "WebAssembly threads support.";
 const char kEnableWasmThreadsDescription[] =
     "Enables support for the WebAssembly Threads proposal. Implies "
@@ -1631,10 +1635,6 @@
     "verdicts from Safe Browsing. These will provide stronger protections "
     "from files Safe Browsing is unsure about.";
 
-const char kSafeSearchUrlReportingName[] = "SafeSearch URLs reporting.";
-const char kSafeSearchUrlReportingDescription[] =
-    "If enabled, inappropriate URLs can be reported back to SafeSearch.";
-
 const char kSameSiteByDefaultCookiesName[] = "SameSite by default cookies";
 const char kSameSiteByDefaultCookiesDescription[] =
     "Treat cookies that don't specify a SameSite attribute as if they were "
@@ -2722,6 +2722,12 @@
     "Reverse the logic of suggestions that have a tab switch button: Have "
     "them switch by default, and have the button navigate.";
 
+const char kOmniboxShortBookmarkSuggestionsName[] =
+    "Omnibox short bookmark suggestions";
+const char kOmniboxShortBookmarkSuggestionsDescription[] =
+    "Match very short input words to beginning of words in bookmark "
+    "suggestions.";
+
 const char kOmniboxSuggestionTransparencyOptionsName[] =
     "Omnibox Suggestion Transparency Options";
 const char kOmniboxSuggestionTransparencyOptionsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 58ac754..82bdd4b 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -572,6 +572,9 @@
 extern const char kEnableWasmCodeCacheName[];
 extern const char kEnableWasmCodeCacheDescription[];
 
+extern const char kEnableWasmSimdName[];
+extern const char kEnableWasmSimdDescription[];
+
 extern const char kEnableWasmThreadsName[];
 extern const char kEnableWasmThreadsDescription[];
 
@@ -815,6 +818,9 @@
 extern const char kOmniboxRichEntitySuggestionsName[];
 extern const char kOmniboxRichEntitySuggestionsDescription[];
 
+extern const char kOmniboxShortBookmarkSuggestionsName[];
+extern const char kOmniboxShortBookmarkSuggestionsDescription[];
+
 extern const char kOmniboxSpareRendererName[];
 extern const char kOmniboxSpareRendererDescription[];
 
@@ -979,9 +985,6 @@
 extern const char kSafeBrowsingUseAPDownloadVerdictsName[];
 extern const char kSafeBrowsingUseAPDownloadVerdictsDescription[];
 
-extern const char kSafeSearchUrlReportingName[];
-extern const char kSafeSearchUrlReportingDescription[];
-
 extern const char kSameSiteByDefaultCookiesName[];
 extern const char kSameSiteByDefaultCookiesDescription[];
 
diff --git a/chrome/browser/geolocation/geolocation_permission_context.cc b/chrome/browser/geolocation/geolocation_permission_context.cc
index 4e1a289..d3538bcc 100644
--- a/chrome/browser/geolocation/geolocation_permission_context.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context.cc
@@ -31,33 +31,30 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   bool permission_set;
   bool new_permission;
   if (extensions_context_.DecidePermission(
-      web_contents, id, id.request_id(), requesting_origin, user_gesture,
-      callback, &permission_set, &new_permission)) {
+          web_contents, id, id.request_id(), requesting_origin, user_gesture,
+          &callback, &permission_set, &new_permission)) {
+    DCHECK_EQ(!!callback, permission_set);
     if (permission_set) {
       ContentSetting content_setting =
           new_permission ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
-      NotifyPermissionSet(id,
-                          requesting_origin,
+      NotifyPermissionSet(id, requesting_origin,
                           web_contents->GetLastCommittedURL().GetOrigin(),
-                          callback,
-                          false /* persist */,
+                          std::move(callback), false /* persist */,
                           content_setting);
     }
     return;
   }
+  DCHECK(callback);
 
-  PermissionContextBase::DecidePermission(web_contents,
-                                          id,
-                                          requesting_origin,
-                                          embedding_origin,
-                                          user_gesture,
-                                          callback);
+  PermissionContextBase::DecidePermission(web_contents, id, requesting_origin,
+                                          embedding_origin, user_gesture,
+                                          std::move(callback));
 }
 
 void GeolocationPermissionContext::UpdateTabContext(
diff --git a/chrome/browser/geolocation/geolocation_permission_context.h b/chrome/browser/geolocation/geolocation_permission_context.h
index 8af3a433..6173e71 100644
--- a/chrome/browser/geolocation/geolocation_permission_context.h
+++ b/chrome/browser/geolocation/geolocation_permission_context.h
@@ -31,7 +31,7 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
 
  private:
   void UpdateTabContext(const PermissionRequestID& id,
diff --git a/chrome/browser/geolocation/geolocation_permission_context_android.cc b/chrome/browser/geolocation/geolocation_permission_context_android.cc
index 64cf07bf..d5f2710 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_android.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context_android.cc
@@ -110,12 +110,13 @@
     const PermissionRequestID& id,
     const GURL& requesting_frame_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   if (!IsLocationAccessPossible(web_contents, requesting_frame_origin,
                                 user_gesture)) {
     NotifyPermissionSet(id, requesting_frame_origin,
                         web_contents->GetLastCommittedURL().GetOrigin(),
-                        callback, false /* persist */, CONTENT_SETTING_BLOCK);
+                        std::move(callback), false /* persist */,
+                        CONTENT_SETTING_BLOCK);
     return;
   }
 
@@ -136,13 +137,14 @@
         base::BindOnce(&GeolocationPermissionContextAndroid ::
                            HandleUpdateAndroidPermissions,
                        weak_factory_.GetWeakPtr(), id, requesting_frame_origin,
-                       embedding_origin, callback));
+                       embedding_origin, std::move(callback)));
 
     return;
   }
 
   GeolocationPermissionContext::RequestPermission(
-      web_contents, id, requesting_frame_origin, user_gesture, callback);
+      web_contents, id, requesting_frame_origin, user_gesture,
+      std::move(callback));
 }
 
 void GeolocationPermissionContextAndroid::UserMadePermissionDecision(
@@ -160,7 +162,7 @@
     const PermissionRequestID& id,
     const GURL& requesting_origin,
     const GURL& embedding_origin,
-    const BrowserPermissionCallback& callback,
+    BrowserPermissionCallback callback,
     bool persist,
     ContentSetting content_setting) {
   bool is_default_search = IsRequestingOriginDSE(requesting_origin);
@@ -174,7 +176,7 @@
     // would reset the backoff.
     if (IsInLocationSettingsBackOff(is_default_search)) {
       FinishNotifyPermissionSet(id, requesting_origin, embedding_origin,
-                                callback, false /* persist */,
+                                std::move(callback), false /* persist */,
                                 CONTENT_SETTING_BLOCK);
       LogLocationSettingsMetric(
           kLocationSettingsSuppressMetricBase, is_default_search,
@@ -200,7 +202,7 @@
     if ((tab && !tab->IsUserInteractable()) ||
         !location_settings_dialog_callback_.is_null()) {
       FinishNotifyPermissionSet(id, requesting_origin, embedding_origin,
-                                callback, false /* persist */,
+                                std::move(callback), false /* persist */,
                                 CONTENT_SETTING_BLOCK);
       // This case should be very rare, so just pretend it was a denied prompt
       // for metrics purposes.
@@ -211,7 +213,7 @@
     }
 
     location_settings_dialog_request_id_ = id;
-    location_settings_dialog_callback_ = callback;
+    location_settings_dialog_callback_ = std::move(callback);
     location_settings_->PromptToEnableSystemLocationSetting(
         is_default_search ? SEARCH : DEFAULT, web_contents,
         base::BindOnce(
@@ -221,8 +223,8 @@
     return;
   }
 
-  FinishNotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
-                            persist, content_setting);
+  FinishNotifyPermissionSet(id, requesting_origin, embedding_origin,
+                            std::move(callback), persist, content_setting);
 }
 
 PermissionResult
@@ -375,14 +377,14 @@
     const PermissionRequestID& id,
     const GURL& requesting_frame_origin,
     const GURL& embedding_origin,
-    const BrowserPermissionCallback& callback,
+    BrowserPermissionCallback callback,
     bool permissions_updated) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   ContentSetting new_setting = permissions_updated
       ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
 
-  NotifyPermissionSet(id, requesting_frame_origin, embedding_origin, callback,
-                      false /* persist */, new_setting);
+  NotifyPermissionSet(id, requesting_frame_origin, embedding_origin,
+                      std::move(callback), false /* persist */, new_setting);
 }
 
 bool GeolocationPermissionContextAndroid::CanShowLocationSettingsDialog(
@@ -431,27 +433,26 @@
 
   // If the permission was cancelled while the LSD was up, the callback has
   // already been dropped.
-  if (location_settings_dialog_callback_.is_null())
+  if (!location_settings_dialog_callback_)
     return;
 
   FinishNotifyPermissionSet(
       location_settings_dialog_request_id_, requesting_origin, embedding_origin,
-      location_settings_dialog_callback_, persist, content_setting);
+      std::move(location_settings_dialog_callback_), persist, content_setting);
 
   location_settings_dialog_request_id_ = PermissionRequestID(0, 0, 0);
-  location_settings_dialog_callback_.Reset();
 }
 
 void GeolocationPermissionContextAndroid::FinishNotifyPermissionSet(
     const PermissionRequestID& id,
     const GURL& requesting_origin,
     const GURL& embedding_origin,
-    const BrowserPermissionCallback& callback,
+    BrowserPermissionCallback callback,
     bool persist,
     ContentSetting content_setting) {
-  GeolocationPermissionContext::NotifyPermissionSet(id, requesting_origin,
-                                                    embedding_origin, callback,
-                                                    persist, content_setting);
+  GeolocationPermissionContext::NotifyPermissionSet(
+      id, requesting_origin, embedding_origin, std::move(callback), persist,
+      content_setting);
 
   // If this is the default search origin, and the DSE Geolocation setting is
   // being used, potentially show the disclosure.
diff --git a/chrome/browser/geolocation/geolocation_permission_context_android.h b/chrome/browser/geolocation/geolocation_permission_context_android.h
index 106568f..518145c5 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_android.h
+++ b/chrome/browser/geolocation/geolocation_permission_context_android.h
@@ -68,12 +68,11 @@
   static void SetDSEOriginForTesting(const char* dse_origin);
 
   // GeolocationPermissionContext:
-  void RequestPermission(
-      content::WebContents* web_contents,
-      const PermissionRequestID& id,
-      const GURL& requesting_frame_origin,
-      bool user_gesture,
-      const BrowserPermissionCallback& callback) override;
+  void RequestPermission(content::WebContents* web_contents,
+                         const PermissionRequestID& id,
+                         const GURL& requesting_frame_origin,
+                         bool user_gesture,
+                         BrowserPermissionCallback callback) override;
   void UserMadePermissionDecision(const PermissionRequestID& id,
                                   const GURL& requesting_origin,
                                   const GURL& embedding_origin,
@@ -81,7 +80,7 @@
   void NotifyPermissionSet(const PermissionRequestID& id,
                            const GURL& requesting_origin,
                            const GURL& embedding_origin,
-                           const BrowserPermissionCallback& callback,
+                           BrowserPermissionCallback callback,
                            bool persist,
                            ContentSetting content_setting) override;
   PermissionResult UpdatePermissionStatusWithDeviceStatus(
@@ -110,7 +109,7 @@
   void HandleUpdateAndroidPermissions(const PermissionRequestID& id,
                                       const GURL& requesting_frame_origin,
                                       const GURL& embedding_origin,
-                                      const BrowserPermissionCallback& callback,
+                                      BrowserPermissionCallback callback,
                                       bool permissions_updated);
 
   // Will return true if the location settings dialog will be shown for the
@@ -131,7 +130,7 @@
   void FinishNotifyPermissionSet(const PermissionRequestID& id,
                                  const GURL& requesting_origin,
                                  const GURL& embedding_origin,
-                                 const BrowserPermissionCallback& callback,
+                                 BrowserPermissionCallback callback,
                                  bool persist,
                                  ContentSetting content_setting);
 
diff --git a/chrome/browser/geolocation/geolocation_permission_context_extensions.cc b/chrome/browser/geolocation/geolocation_permission_context_extensions.cc
index 111cc9bd..b717749 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_extensions.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context_extensions.cc
@@ -26,9 +26,10 @@
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 void CallbackContentSettingWrapper(
-    const base::Callback<void(ContentSetting)>& callback,
+    base::OnceCallback<void(ContentSetting)> callback,
     bool allowed) {
-  callback.Run(allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
+  std::move(callback).Run(allowed ? CONTENT_SETTING_ALLOW
+                                  : CONTENT_SETTING_BLOCK);
 }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
@@ -52,7 +53,7 @@
     int bridge_id,
     const GURL& requesting_frame,
     bool user_gesture,
-    const base::Callback<void(ContentSetting)>& callback,
+    base::OnceCallback<void(ContentSetting)>* callback,
     bool* permission_set,
     bool* new_permission) {
 #if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -63,7 +64,7 @@
   if (web_view_permission_helper) {
     web_view_permission_helper->RequestGeolocationPermission(
         bridge_id, requesting_frame, user_gesture,
-        base::Bind(&CallbackContentSettingWrapper, callback));
+        base::BindOnce(&CallbackContentSettingWrapper, std::move(*callback)));
     *permission_set = false;
     *new_permission = false;
     return true;
diff --git a/chrome/browser/geolocation/geolocation_permission_context_extensions.h b/chrome/browser/geolocation/geolocation_permission_context_extensions.h
index bf96695..c219518e 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_extensions.h
+++ b/chrome/browser/geolocation/geolocation_permission_context_extensions.h
@@ -26,13 +26,15 @@
 
   // Returns true if the permission request was handled. In which case,
   // |permission_set| will be set to true if the permission changed, and the
-  // permission has been set to |new_permission|.
+  // permission has been set to |new_permission|. Consumes |callback| if it
+  // returns true while setting |permission_set| to false, otherwise |callback|
+  // is not used.
   bool DecidePermission(content::WebContents* web_contents,
                         const PermissionRequestID& request_id,
                         int bridge_id,
                         const GURL& requesting_frame,
                         bool user_gesture,
-                        const base::Callback<void(ContentSetting)>& callback,
+                        base::OnceCallback<void(ContentSetting)>* callback,
                         bool* permission_set,
                         bool* new_permission);
 
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
index 59bff3c..bbcfdeb 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
@@ -28,9 +28,9 @@
 
 namespace {
 
-void CallbackWrapper(const base::Callback<void(bool)>& callback,
+void CallbackWrapper(base::OnceCallback<void(bool)> callback,
                      ContentSetting status) {
-  callback.Run(status == CONTENT_SETTING_ALLOW);
+  std::move(callback).Run(status == CONTENT_SETTING_ALLOW);
 }
 
 }  // anonymous namespace
@@ -145,7 +145,7 @@
     int bridge_id,
     const GURL& requesting_frame,
     bool user_gesture,
-    const base::Callback<void(bool)>& callback) {
+    base::OnceCallback<void(bool)> callback) {
   base::DictionaryValue request_info;
   request_info.SetString(guest_view::kUrl, requesting_frame.spec());
   request_info.SetBoolean(guest_view::kUserGesture, user_gesture);
@@ -157,7 +157,7 @@
       base::BindOnce(&ChromeWebViewPermissionHelperDelegate::
                          OnGeolocationPermissionResponse,
                      weak_factory_.GetWeakPtr(), bridge_id, user_gesture,
-                     base::Bind(&CallbackWrapper, callback));
+                     base::BindOnce(&CallbackWrapper, std::move(callback)));
   int request_id = web_view_permission_helper()->RequestPermission(
       WEB_VIEW_PERMISSION_TYPE_GEOLOCATION, request_info,
       std::move(permission_callback), false /* allowed_by_default */);
@@ -167,7 +167,7 @@
 void ChromeWebViewPermissionHelperDelegate::OnGeolocationPermissionResponse(
     int bridge_id,
     bool user_gesture,
-    const base::Callback<void(ContentSetting)>& callback,
+    base::OnceCallback<void(ContentSetting)> callback,
     bool allow,
     const std::string& user_input) {
   // The <webview> embedder has allowed the permission. We now need to make sure
@@ -175,7 +175,7 @@
   RemoveBridgeID(bridge_id);
 
   if (!allow || !web_view_guest()->attached()) {
-    callback.Run(CONTENT_SETTING_BLOCK);
+    std::move(callback).Run(CONTENT_SETTING_BLOCK);
     return;
   }
 
@@ -201,8 +201,7 @@
           ->embedder_web_contents()
           ->GetLastCommittedURL()
           .GetOrigin(),
-      user_gesture,
-      callback);
+      user_gesture, std::move(callback));
 }
 
 void ChromeWebViewPermissionHelperDelegate::CancelGeolocationPermissionRequest(
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h
index 6b78b19..9bdf351 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h
@@ -38,7 +38,7 @@
       int bridge_id,
       const GURL& requesting_frame,
       bool user_gesture,
-      const base::Callback<void(bool)>& callback) override;
+      base::OnceCallback<void(bool)> callback) override;
   void CancelGeolocationPermissionRequest(int bridge_id) override;
   void RequestFileSystemPermission(
       const GURL& url,
@@ -74,7 +74,7 @@
   void OnGeolocationPermissionResponse(
       int bridge_id,
       bool user_gesture,
-      const base::Callback<void(ContentSetting)>& callback,
+      base::OnceCallback<void(ContentSetting)> callback,
       bool allow,
       const std::string& user_input);
 
diff --git a/chrome/browser/media/protected_media_identifier_permission_context.cc b/chrome/browser/media/protected_media_identifier_permission_context.cc
index 249622c..903efe90 100644
--- a/chrome/browser/media/protected_media_identifier_permission_context.cc
+++ b/chrome/browser/media/protected_media_identifier_permission_context.cc
@@ -62,32 +62,36 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // Since the dialog is modal, we only support one prompt per |web_contents|.
   // Reject the new one if there is already one pending. See
   // http://crbug.com/447005
   if (pending_requests_.count(web_contents)) {
-    callback.Run(CONTENT_SETTING_ASK);
+    std::move(callback).Run(CONTENT_SETTING_ASK);
     return;
   }
 
+  // ShowDialog doesn't use the callback if it returns null.
+  auto repeating_callback =
+      base::AdaptCallbackForRepeating(std::move(callback));
+
   // On ChromeOS, we don't use PermissionContextBase::RequestPermission() which
   // uses the standard permission infobar/bubble UI. See http://crbug.com/454847
   // Instead, we show the existing platform verification UI.
   // TODO(xhwang): Remove when http://crbug.com/454847 is fixed.
   views::Widget* widget = PlatformVerificationDialog::ShowDialog(
       web_contents, requesting_origin,
-      base::Bind(&ProtectedMediaIdentifierPermissionContext::
-                     OnPlatformVerificationConsentResponse,
-                 weak_factory_.GetWeakPtr(), web_contents, id,
-                 requesting_origin, embedding_origin, callback));
+      base::BindOnce(&ProtectedMediaIdentifierPermissionContext::
+                         OnPlatformVerificationConsentResponse,
+                     weak_factory_.GetWeakPtr(), web_contents, id,
+                     requesting_origin, embedding_origin, repeating_callback));
 
   // This could happen when the permission is requested from an extension. See
   // http://crbug.com/728534
   if (!widget) {
-    callback.Run(CONTENT_SETTING_ASK);
+    std::move(repeating_callback).Run(CONTENT_SETTING_ASK);
     return;
   }
 
@@ -217,7 +221,7 @@
         const PermissionRequestID& id,
         const GURL& requesting_origin,
         const GURL& embedding_origin,
-        const BrowserPermissionCallback& callback,
+        BrowserPermissionCallback callback,
         PlatformVerificationDialog::ConsentResponse response) {
   // The request may have been canceled. Drop the callback in that case.
   // This can happen if the tab is closed.
@@ -260,8 +264,7 @@
       break;
   }
 
-  NotifyPermissionSet(
-      id, requesting_origin, embedding_origin, callback,
-      persist, content_setting);
+  NotifyPermissionSet(id, requesting_origin, embedding_origin,
+                      std::move(callback), persist, content_setting);
 }
 #endif
diff --git a/chrome/browser/media/protected_media_identifier_permission_context.h b/chrome/browser/media/protected_media_identifier_permission_context.h
index 08d09b9f..ad23493 100644
--- a/chrome/browser/media/protected_media_identifier_permission_context.h
+++ b/chrome/browser/media/protected_media_identifier_permission_context.h
@@ -43,7 +43,7 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
 #endif  // defined(OS_CHROMEOS)
   ContentSetting GetPermissionStatusInternal(
       content::RenderFrameHost* render_frame_host,
@@ -71,7 +71,7 @@
       const PermissionRequestID& id,
       const GURL& requesting_origin,
       const GURL& embedding_origin,
-      const BrowserPermissionCallback& callback,
+      BrowserPermissionCallback callback,
       chromeos::attestation::PlatformVerificationDialog::ConsentResponse
           response);
 
diff --git a/chrome/browser/media/webrtc/media_stream_device_permission_context.cc b/chrome/browser/media/webrtc/media_stream_device_permission_context.cc
index eee1469..b64eea23 100644
--- a/chrome/browser/media/webrtc/media_stream_device_permission_context.cc
+++ b/chrome/browser/media/webrtc/media_stream_device_permission_context.cc
@@ -44,10 +44,10 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   PermissionContextBase::DecidePermission(web_contents, id, requesting_origin,
                                           embedding_origin, user_gesture,
-                                          callback);
+                                          std::move(callback));
 }
 
 ContentSetting MediaStreamDevicePermissionContext::GetPermissionStatusInternal(
diff --git a/chrome/browser/media/webrtc/media_stream_device_permission_context.h b/chrome/browser/media/webrtc/media_stream_device_permission_context.h
index 8c607f1..9a19834 100644
--- a/chrome/browser/media/webrtc/media_stream_device_permission_context.h
+++ b/chrome/browser/media/webrtc/media_stream_device_permission_context.h
@@ -22,7 +22,7 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
 
   // TODO(xhwang): GURL.GetOrigin() shouldn't be used as the origin. Need to
   // refactor to use url::Origin. crbug.com/527149 is filed for this.
diff --git a/chrome/browser/notifications/notification_permission_context.cc b/chrome/browser/notifications/notification_permission_context.cc
index b65111d..c88d0fe 100644
--- a/chrome/browser/notifications/notification_permission_context.cc
+++ b/chrome/browser/notifications/notification_permission_context.cc
@@ -51,7 +51,7 @@
   // Runs |task| after the WebContents has been visible for a consecutive
   // duration of at least |visible_delay|.
   void PostTaskAfterVisibleDelay(const base::Location& from_here,
-                                 const base::Closure& task,
+                                 base::OnceClosure task,
                                  base::TimeDelta visible_delay,
                                  const PermissionRequestID& id);
 
@@ -66,7 +66,7 @@
   friend class content::WebContentsUserData<VisibilityTimerTabHelper>;
   explicit VisibilityTimerTabHelper(content::WebContents* contents);
 
-  void RunTask(const base::Closure& task);
+  void RunTask(base::OnceClosure task);
 
   bool is_visible_;
 
@@ -117,18 +117,21 @@
 
 void VisibilityTimerTabHelper::PostTaskAfterVisibleDelay(
     const base::Location& from_here,
-    const base::Closure& task,
+    base::OnceClosure task,
     base::TimeDelta visible_delay,
     const PermissionRequestID& id) {
   if (web_contents()->IsBeingDestroyed())
     return;
 
-  // Safe to use Unretained, as destroying this will destroy task_queue_, hence
-  // cancelling all timers.
+  // Safe to use Unretained, as destroying |this| will destroy task_queue_,
+  // hence cancelling all timers.
+  // RetainingOneShotTimer is used which needs a RepeatingCallback, but we
+  // only have it run this callback a single time, and destroy it after.
   auto timer = std::make_unique<base::RetainingOneShotTimer>(
       from_here, visible_delay,
-      base::Bind(&VisibilityTimerTabHelper::RunTask, base::Unretained(this),
-                 task));
+      base::AdaptCallbackForRepeating(
+          base::BindOnce(&VisibilityTimerTabHelper::RunTask,
+                         base::Unretained(this), std::move(task))));
   DCHECK(!timer->IsRunning());
 
   task_queue_.emplace_back(id, std::move(timer));
@@ -163,9 +166,9 @@
   task_queue_.clear();
 }
 
-void VisibilityTimerTabHelper::RunTask(const base::Closure& task) {
+void VisibilityTimerTabHelper::RunTask(base::OnceClosure task) {
   DCHECK(is_visible_);
-  task.Run();
+  std::move(task).Run();
   task_queue_.pop_front();
   if (!task_queue_.empty())
     task_queue_.front().timer->Reset();
@@ -265,7 +268,7 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // Permission requests for either Web Notifications and Push Notifications may
@@ -274,7 +277,7 @@
   // around the restriction by posting a message to their Service Worker, where
   // showing a notification is allowed.
   if (requesting_origin != embedding_origin) {
-    callback.Run(CONTENT_SETTING_BLOCK);
+    std::move(callback).Run(CONTENT_SETTING_BLOCK);
     return;
   }
 
@@ -292,17 +295,18 @@
     VisibilityTimerTabHelper::FromWebContents(web_contents)
         ->PostTaskAfterVisibleDelay(
             FROM_HERE,
-            base::Bind(&NotificationPermissionContext::NotifyPermissionSet,
-                       weak_factory_ui_thread_.GetWeakPtr(), id,
-                       requesting_origin, embedding_origin, callback,
-                       true /* persist */, CONTENT_SETTING_BLOCK),
+            base::BindOnce(&NotificationPermissionContext::NotifyPermissionSet,
+                           weak_factory_ui_thread_.GetWeakPtr(), id,
+                           requesting_origin, embedding_origin,
+                           std::move(callback), true /* persist */,
+                           CONTENT_SETTING_BLOCK),
             base::TimeDelta::FromSecondsD(delay_seconds), id);
     return;
   }
 
   PermissionContextBase::DecidePermission(web_contents, id, requesting_origin,
                                           embedding_origin, user_gesture,
-                                          callback);
+                                          std::move(callback));
 }
 
 // Unlike other permission types, granting a notification for a given origin
diff --git a/chrome/browser/notifications/notification_permission_context.h b/chrome/browser/notifications/notification_permission_context.h
index 23200bdc..0db5a6ed 100644
--- a/chrome/browser/notifications/notification_permission_context.h
+++ b/chrome/browser/notifications/notification_permission_context.h
@@ -119,7 +119,7 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
   void UpdateContentSetting(const GURL& requesting_origin,
                             const GURL& embedder_origin,
                             ContentSetting content_setting) override;
diff --git a/chrome/browser/notifications/notification_permission_context_unittest.cc b/chrome/browser/notifications/notification_permission_context_unittest.cc
index f83772c..6e79ba0e 100644
--- a/chrome/browser/notifications/notification_permission_context_unittest.cc
+++ b/chrome/browser/notifications/notification_permission_context_unittest.cc
@@ -83,14 +83,14 @@
   void NotifyPermissionSet(const PermissionRequestID& id,
                            const GURL& requesting_origin,
                            const GURL& embedder_origin,
-                           const BrowserPermissionCallback& callback,
+                           BrowserPermissionCallback callback,
                            bool persist,
                            ContentSetting content_setting) override {
     permission_set_count_++;
     last_permission_set_persisted_ = persist;
     last_permission_set_setting_ = content_setting;
     NotificationPermissionContext::NotifyPermissionSet(
-        id, requesting_origin, embedder_origin, callback, persist,
+        id, requesting_origin, embedder_origin, std::move(callback), persist,
         content_setting);
   }
 
diff --git a/chrome/browser/offline_pages/android/prefetch_background_task_android.cc b/chrome/browser/offline_pages/android/prefetch_background_task_android.cc
index c1fffdf3..5d11c0f4 100644
--- a/chrome/browser/offline_pages/android/prefetch_background_task_android.cc
+++ b/chrome/browser/offline_pages/android/prefetch_background_task_android.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_android.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "components/offline_pages/core/prefetch/prefetch_background_task.h"
 #include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
 #include "components/offline_pages/core/prefetch/prefetch_service.h"
@@ -28,9 +29,8 @@
 static jboolean JNI_PrefetchBackgroundTask_StartPrefetchTask(
     JNIEnv* env,
     const JavaParamRef<jobject>& jcaller,
-    const JavaParamRef<jobject>& jprofile,
     const JavaParamRef<jstring>& gcm_token) {
-  Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile);
+  Profile* profile = ProfileManager::GetLastUsedProfile();
   DCHECK(profile);
 
   PrefetchService* prefetch_service =
diff --git a/chrome/browser/offline_pages/prefetch/prefetch_instance_id_proxy.cc b/chrome/browser/offline_pages/prefetch/prefetch_instance_id_proxy.cc
index 1f5a7b4..39ec3760 100644
--- a/chrome/browser/offline_pages/prefetch/prefetch_instance_id_proxy.cc
+++ b/chrome/browser/offline_pages/prefetch/prefetch_instance_id_proxy.cc
@@ -41,9 +41,10 @@
   DCHECK(IsPrefetchingOfflinePagesEnabled());
   if (!token_.empty()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(&PrefetchInstanceIDProxy::GotGCMToken,
-                                  weak_factory_.GetWeakPtr(), callback, token_,
-                                  InstanceID::SUCCESS));
+        FROM_HERE,
+        base::BindOnce(&PrefetchInstanceIDProxy::GotGCMToken,
+                       weak_factory_.GetWeakPtr(), std::move(callback), token_,
+                       InstanceID::SUCCESS));
     return;
   }
 
@@ -54,10 +55,11 @@
   InstanceID* instance_id = service->driver()->GetInstanceID(app_id_);
   DCHECK(instance_id);
 
-  instance_id->GetToken(kProdSenderId, kScopeGCM,
-                        std::map<std::string, std::string>(), /*is_lazy=*/false,
-                        base::Bind(&PrefetchInstanceIDProxy::GotGCMToken,
-                                   weak_factory_.GetWeakPtr(), callback));
+  instance_id->GetToken(
+      kProdSenderId, kScopeGCM, std::map<std::string, std::string>(),
+      /*is_lazy=*/false,
+      base::BindOnce(&PrefetchInstanceIDProxy::GotGCMToken,
+                     weak_factory_.GetWeakPtr(), std::move(callback)));
 }
 
 void PrefetchInstanceIDProxy::GotGCMToken(InstanceID::GetTokenCallback callback,
@@ -65,7 +67,7 @@
                                           InstanceID::Result result) {
   DVLOG(1) << "Got an Instance ID token for GCM: " << token
            << " with result: " << result;
-  callback.Run(token, result);
+  std::move(callback).Run(token, result);
 }
 
 }  // namespace offline_pages
diff --git a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc
index d2ee8ed..9e3ee38 100644
--- a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc
@@ -62,9 +62,25 @@
     return STOP_OBSERVING;
 
   committed_preview_ = previews_user_data->committed_previews_type();
+
+  // Only check for preview types that are decided before commit in the
+  // |allowed_previews_state|.
+  previews_likely_ = HasEnabledPreviews(
+      previews_user_data->allowed_previews_state() & kPreCommitPreviews);
+
+  // Check all preview types in the |committed_previews_state|. In practice
+  // though, this will only set |previews_likely_| if it wasn't before for an
+  // Optimization Hints preview.
+  previews_likely_ |=
+      HasEnabledPreviews(previews_user_data->committed_previews_state());
+
+  coin_flip_result_ = previews_user_data->coin_flip_holdback_result();
   content::PreviewsState previews_state =
       previews_user_data->committed_previews_state();
 
+  if (coin_flip_result_ != CoinFlipHoldbackResult::kNotSet)
+    DCHECK(previews_likely_);
+
   if (navigation_handle->GetWebContents()->GetContentsMimeType() ==
       kOfflinePreviewsMimeType) {
     if (!IsOfflinePreview(navigation_handle->GetWebContents()))
@@ -176,6 +192,7 @@
   }
 
   ukm::builders::Previews builder(info.source_id);
+  builder.Setcoin_flip_result(static_cast<int>(coin_flip_result_));
   if (server_lofi_seen_)
     builder.Setserver_lofi(1);
   if (client_lofi_seen_)
@@ -196,6 +213,8 @@
     builder.Setorigin_opt_out(1);
   if (save_data_enabled_)
     builder.Setsave_data_enabled(1);
+  if (previews_likely_)
+    builder.Setpreviews_likely(1);
   if (navigation_restart_penalty_.has_value()) {
     builder.Setnavigation_restart_penalty(
         navigation_restart_penalty_->InMilliseconds());
diff --git a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.h b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.h
index 4373fa09..6739004 100644
--- a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.h
+++ b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.h
@@ -72,6 +72,8 @@
   bool opt_out_occurred_ = false;
   bool origin_opt_out_occurred_ = false;
   bool save_data_enabled_ = false;
+  bool previews_likely_ = false;
+  CoinFlipHoldbackResult coin_flip_result_ = CoinFlipHoldbackResult::kNotSet;
   base::Optional<base::TimeDelta> navigation_restart_penalty_ = base::nullopt;
 
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc
index c61e076b..8845d19d 100644
--- a/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc
@@ -40,6 +40,7 @@
  public:
   TestPreviewsUKMObserver(
       PreviewsType committed_preview,
+      content::PreviewsState allowed_state,
       bool lite_page_received,
       bool lite_page_redirect_received,
       bool noscript_on,
@@ -47,8 +48,10 @@
       bool origin_opt_out_received,
       bool save_data_enabled,
       bool is_offline_preview,
+      CoinFlipHoldbackResult coin_flip_result,
       base::Optional<base::TimeDelta> navigation_restart_penalty)
       : committed_preview_(committed_preview),
+        allowed_state_(allowed_state),
         lite_page_received_(lite_page_received),
         lite_page_redirect_received_(lite_page_redirect_received),
         noscript_on_(noscript_on),
@@ -56,6 +59,7 @@
         origin_opt_out_received_(origin_opt_out_received),
         save_data_enabled_(save_data_enabled),
         is_offline_preview_(is_offline_preview),
+        coin_flip_result_(coin_flip_result),
         navigation_restart_penalty_(navigation_restart_penalty) {}
 
   ~TestPreviewsUKMObserver() override {}
@@ -70,6 +74,8 @@
             navigation_handle, 1u);
 
     user_data->SetCommittedPreviewsTypeForTesting(committed_preview_);
+    user_data->set_allowed_previews_state(allowed_state_);
+    user_data->set_coin_flip_holdback_result(coin_flip_result_);
 
     if (noscript_on_) {
       content::PreviewsState previews_state =
@@ -132,6 +138,7 @@
   }
 
   PreviewsType committed_preview_;
+  content::PreviewsState allowed_state_;
   bool lite_page_received_;
   bool lite_page_redirect_received_;
   bool noscript_on_;
@@ -139,6 +146,7 @@
   bool origin_opt_out_received_;
   const bool save_data_enabled_;
   const bool is_offline_preview_;
+  CoinFlipHoldbackResult coin_flip_result_;
   base::Optional<base::TimeDelta> navigation_restart_penalty_;
 
   DISALLOW_COPY_AND_ASSIGN(TestPreviewsUKMObserver);
@@ -150,7 +158,8 @@
   PreviewsUKMObserverTest() {}
   ~PreviewsUKMObserverTest() override {}
 
-  void RunTest(PreviewsType committed_preview,
+  void RunTest(content::PreviewsState allowed_state,
+               PreviewsType committed_preview,
                bool lite_page_received,
                bool lite_page_redirect_received,
                bool noscript_on,
@@ -158,8 +167,10 @@
                bool origin_opt_out,
                bool save_data_enabled,
                bool is_offline_preview,
+               CoinFlipHoldbackResult coin_flip_result,
                base::Optional<base::TimeDelta> navigation_restart_penalty) {
     committed_preview_ = committed_preview;
+    allowed_state_ = allowed_state;
     lite_page_received_ = lite_page_received;
     lite_page_redirect_received_ = lite_page_redirect_received;
     noscript_on_ = noscript_on;
@@ -167,6 +178,7 @@
     origin_opt_out_ = origin_opt_out;
     save_data_enabled_ = save_data_enabled;
     is_offline_preview_ = is_offline_preview;
+    coin_flip_result_ = coin_flip_result;
     navigation_restart_penalty_ = navigation_restart_penalty;
     auto navigation = content::NavigationSimulator::CreateBrowserInitiated(
         GURL(kDefaultTestUrl), web_contents());
@@ -186,6 +198,8 @@
                    bool origin_opt_out_expected,
                    bool save_data_enabled_expected,
                    bool offline_preview_expected,
+                   bool previews_likely_expected,
+                   CoinFlipHoldbackResult coin_flip_result_expected,
                    base::Optional<base::TimeDelta> navigation_restart_penalty) {
     using UkmEntry = ukm::builders::Previews;
     auto entries = test_ukm_recorder().GetEntriesByName(UkmEntry::kEntryName);
@@ -193,7 +207,9 @@
         !lite_page_redirect_expected && !noscript_expected &&
         !resource_loading_hints_expected && opt_out_value == 0 &&
         !origin_opt_out_expected && !save_data_enabled_expected &&
-        !offline_preview_expected && !navigation_restart_penalty.has_value()) {
+        !offline_preview_expected && !previews_likely_expected &&
+        coin_flip_result_expected == CoinFlipHoldbackResult::kNotSet &&
+        !navigation_restart_penalty.has_value()) {
       EXPECT_EQ(0u, entries.size());
       return;
     }
@@ -229,6 +245,12 @@
       EXPECT_EQ(save_data_enabled_expected,
                 test_ukm_recorder().EntryHasMetric(
                     entry, UkmEntry::ksave_data_enabledName));
+      EXPECT_EQ(previews_likely_expected,
+                test_ukm_recorder().EntryHasMetric(
+                    entry, UkmEntry::kpreviews_likelyName));
+      EXPECT_EQ(static_cast<int>(coin_flip_result_expected),
+                *test_ukm_recorder().GetEntryMetric(
+                    entry, UkmEntry::kcoin_flip_resultName));
       if (navigation_restart_penalty.has_value()) {
         test_ukm_recorder().ExpectEntryMetric(
             entry, UkmEntry::knavigation_restart_penaltyName,
@@ -245,21 +267,25 @@
  protected:
   void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override {
     tracker->AddObserver(std::make_unique<TestPreviewsUKMObserver>(
-        committed_preview_, lite_page_received_, lite_page_redirect_received_,
-        noscript_on_, resource_loading_hints_on_, origin_opt_out_,
-        save_data_enabled_, is_offline_preview_, navigation_restart_penalty_));
+        committed_preview_, allowed_state_, lite_page_received_,
+        lite_page_redirect_received_, noscript_on_, resource_loading_hints_on_,
+        origin_opt_out_, save_data_enabled_, is_offline_preview_,
+        coin_flip_result_, navigation_restart_penalty_));
     // Data is only added to the first navigation after RunTest().
     committed_preview_ = PreviewsType::NONE;
+    allowed_state_ = content::PREVIEWS_OFF;
     lite_page_received_ = false;
     lite_page_redirect_received_ = false;
     noscript_on_ = false;
     resource_loading_hints_on_ = false;
     origin_opt_out_ = false;
+    coin_flip_result_ = CoinFlipHoldbackResult::kNotSet;
     navigation_restart_penalty_ = base::nullopt;
   }
 
  private:
   PreviewsType committed_preview_ = PreviewsType::NONE;
+  content::PreviewsState allowed_state_ = content::PREVIEWS_OFF;
   bool lite_page_received_ = false;
   bool lite_page_redirect_received_ = false;
   bool noscript_on_ = false;
@@ -267,16 +293,19 @@
   bool origin_opt_out_ = false;
   bool save_data_enabled_ = false;
   bool is_offline_preview_ = false;
+  CoinFlipHoldbackResult coin_flip_result_ = CoinFlipHoldbackResult::kNotSet;
   base::Optional<base::TimeDelta> navigation_restart_penalty_ = base::nullopt;
 
   DISALLOW_COPY_AND_ASSIGN(PreviewsUKMObserverTest);
 };
 
 TEST_F(PreviewsUKMObserverTest, NoPreviewSeen) {
-  RunTest(PreviewsType::NONE, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
   NavigateToUntrackedUrl();
 
@@ -287,15 +316,18 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, UntrackedPreviewTypeOptOut) {
-  RunTest(PreviewsType::NONE, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
   NavigateToUntrackedUrl();
@@ -308,15 +340,18 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, LitePageSeen) {
-  RunTest(PreviewsType::NONE, true /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+          true /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   NavigateToUntrackedUrl();
@@ -328,7 +363,8 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -339,10 +375,12 @@
       {previews::features::
            kAndroidOmniboxPreviewsBadge} /* disabled features */);
 
-  RunTest(PreviewsType::LITE_PAGE, true /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::LITE_PAGE, true /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
@@ -355,7 +393,8 @@
               false /* resource_loading_hints_expected */,
               1 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -365,10 +404,12 @@
       {previews::features::kAndroidOmniboxPreviewsBadge} /* enabled features */,
       {} /*disabled features */);
 
-  RunTest(PreviewsType::LITE_PAGE, true /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::LITE_PAGE, true /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
@@ -381,15 +422,18 @@
               false /* resource_loading_hints_expected */,
               2 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, LitePageRedirectSeen) {
-  RunTest(PreviewsType::NONE, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
           true /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   NavigateToUntrackedUrl();
@@ -401,7 +445,8 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -412,10 +457,12 @@
       {previews::features::
            kAndroidOmniboxPreviewsBadge} /* disabled features */);
 
-  RunTest(PreviewsType::LITE_PAGE_REDIRECT, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::LITE_PAGE_REDIRECT, false /* lite_page_received */,
           true /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
@@ -428,7 +475,8 @@
               false /* resource_loading_hints_expected */,
               1 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -438,10 +486,12 @@
       {previews::features::kAndroidOmniboxPreviewsBadge} /* enabled features */,
       {} /*disabled features */);
 
-  RunTest(PreviewsType::LITE_PAGE_REDIRECT, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::LITE_PAGE_REDIRECT, false /* lite_page_received */,
           true /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
@@ -454,15 +504,18 @@
               false /* resource_loading_hints_expected */,
               2 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, NoScriptSeen) {
-  RunTest(PreviewsType::NOSCRIPT, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::NOSCRIPT, false /* lite_page_received */,
           false /* lite_page_redirect_received */, true /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   NavigateToUntrackedUrl();
@@ -473,7 +526,8 @@
       true /* noscript_expected */, false /* resource_loading_hints_expected */,
       0 /* opt_out_value */, false /* origin_opt_out_expected */,
       false /* save_data_enabled_expected */,
-      false /* offline_preview_expected */,
+      false /* offline_preview_expected */, false /* previews_likely */,
+      CoinFlipHoldbackResult::kNotSet,
       base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -484,10 +538,12 @@
       {previews::features::
            kAndroidOmniboxPreviewsBadge} /* disabled features */);
 
-  RunTest(PreviewsType::NOSCRIPT, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::NOSCRIPT, false /* lite_page_received */,
           false /* lite_page_redirect_received */, true /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
@@ -499,7 +555,8 @@
       true /* noscript_expected */, false /* resource_loading_hints_expected */,
       1 /* opt_out_value */, false /* origin_opt_out_expected */,
       false /* save_data_enabled_expected */,
-      false /* offline_preview_expected */,
+      false /* offline_preview_expected */, false /* previews_likely */,
+      CoinFlipHoldbackResult::kNotSet,
       base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -509,10 +566,12 @@
       {previews::features::kAndroidOmniboxPreviewsBadge} /* enabled features */,
       {} /*disabled features */);
 
-  RunTest(PreviewsType::NOSCRIPT, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::NOSCRIPT, false /* lite_page_received */,
           false /* lite_page_redirect_received */, true /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
@@ -524,15 +583,18 @@
       true /* noscript_expected */, false /* resource_loading_hints_expected */,
       2 /* opt_out_value */, false /* origin_opt_out_expected */,
       false /* save_data_enabled_expected */,
-      false /* offline_preview_expected */,
+      false /* offline_preview_expected */, false /* previews_likely */,
+      CoinFlipHoldbackResult::kNotSet,
       base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, OfflinePreviewsSeen) {
-  RunTest(PreviewsType::OFFLINE, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::OFFLINE, false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, true /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   NavigateToUntrackedUrl();
@@ -544,15 +606,18 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              true /* offline_preview_expected */,
+              true /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, ResourceLoadingHintsSeen) {
-  RunTest(PreviewsType::RESOURCE_LOADING_HINTS, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::RESOURCE_LOADING_HINTS, false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           true /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   NavigateToUntrackedUrl();
@@ -563,7 +628,8 @@
       false /* noscript_expected */, true /* resource_loading_hints_expected */,
       0 /* opt_out_value */, false /* origin_opt_out_expected */,
       false /* save_data_enabled_expected */,
-      false /* offline_preview_expected */,
+      false /* offline_preview_expected */, false /* previews_likely */,
+      CoinFlipHoldbackResult::kNotSet,
       base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -574,10 +640,12 @@
       {previews::features::
            kAndroidOmniboxPreviewsBadge} /* disabled features */);
 
-  RunTest(PreviewsType::RESOURCE_LOADING_HINTS, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::RESOURCE_LOADING_HINTS, false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           true /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
@@ -589,7 +657,8 @@
       false /* noscript_expected */, true /* resource_loading_hints_expected */,
       1 /* opt_out_value */, false /* origin_opt_out_expected */,
       false /* save_data_enabled_expected */,
-      false /* offline_preview_expected */,
+      false /* offline_preview_expected */, false /* previews_likely */,
+      CoinFlipHoldbackResult::kNotSet,
       base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -599,10 +668,12 @@
       {previews::features::kAndroidOmniboxPreviewsBadge} /* enabled features */,
       {} /*disabled features */);
 
-  RunTest(PreviewsType::RESOURCE_LOADING_HINTS, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */,
+          PreviewsType::RESOURCE_LOADING_HINTS, false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           true /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey());
@@ -614,15 +685,18 @@
       false /* noscript_expected */, true /* resource_loading_hints_expected */,
       2 /* opt_out_value */, false /* origin_opt_out_expected */,
       false /* save_data_enabled_expected */,
-      false /* offline_preview_expected */,
+      false /* offline_preview_expected */, false /* previews_likely */,
+      CoinFlipHoldbackResult::kNotSet,
       base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, ClientLoFiSeen) {
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data =
@@ -656,7 +730,8 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -667,10 +742,12 @@
       {previews::features::
            kAndroidOmniboxPreviewsBadge} /* disabled features */);
 
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data =
@@ -704,7 +781,8 @@
               false /* resource_loading_hints_expected */,
               1 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -714,10 +792,12 @@
       {previews::features::kAndroidOmniboxPreviewsBadge} /* enabled features */,
       {} /*disabled features */);
 
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data =
@@ -751,15 +831,18 @@
               false /* resource_loading_hints_expected */,
               2 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, ServerLoFiSeen) {
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data =
@@ -793,7 +876,8 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -804,10 +888,12 @@
       {previews::features::
            kAndroidOmniboxPreviewsBadge} /* disabled features */);
 
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data =
@@ -842,7 +928,8 @@
               false /* resource_loading_hints_expected */,
               1 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -852,10 +939,12 @@
       {previews::features::kAndroidOmniboxPreviewsBadge} /* enabled features */,
       {} /*disabled features */);
 
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data =
@@ -890,15 +979,18 @@
               false /* resource_loading_hints_expected */,
               2 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, BothLoFiSeen) {
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data1 =
@@ -937,7 +1029,8 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -948,10 +1041,12 @@
       {previews::features::
            kAndroidOmniboxPreviewsBadge} /* disabled features */);
 
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data1 =
@@ -990,7 +1085,8 @@
               false /* resource_loading_hints_expected */,
               1 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -1000,10 +1096,12 @@
       {previews::features::kAndroidOmniboxPreviewsBadge} /* enabled features */,
       {} /*disabled features */);
 
-  RunTest(PreviewsType::LOFI, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::LOFI,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data1 =
@@ -1042,15 +1140,18 @@
               false /* resource_loading_hints_expected */,
               2 /* opt_out_value */, false /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, OriginOptOut) {
-  RunTest(PreviewsType::NONE, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, true /* origin_opt_out */,
           false /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   NavigateToUntrackedUrl();
@@ -1062,15 +1163,18 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, true /* origin_opt_out_expected */,
               false /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, DataSaverEnabled) {
-  RunTest(PreviewsType::NONE, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           true /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   NavigateToUntrackedUrl();
@@ -1082,7 +1186,8 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               true /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -1090,10 +1195,11 @@
 // committed so we do not consider the opt out tests here.
 TEST_F(PreviewsUKMObserverTest, NavigationRestartPenaltySeen) {
   RunTest(
-      PreviewsType::NONE, false /* lite_page_received */,
-      false /* lite_page_redirect_received */, false /* noscript_on */,
-      false /* resource_loading_hints_on */, false /* origin_opt_out */,
-      false /* save_data_enabled */, false /* is_offline_preview */,
+      content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+      false /* lite_page_received */, false /* lite_page_redirect_received */,
+      false /* noscript_on */, false /* resource_loading_hints_on */,
+      false /* origin_opt_out */, false /* save_data_enabled */,
+      false /* is_offline_preview */, CoinFlipHoldbackResult::kNotSet,
       base::TimeDelta::FromMilliseconds(1337) /* navigation_restart_penalty */);
 
   NavigateToUntrackedUrl();
@@ -1105,15 +1211,133 @@
       false /* resource_loading_hints_expected */, 0 /* opt_out_value */,
       false /* origin_opt_out_expected */,
       false /* save_data_enabled_expected */,
-      false /* offline_preview_expected */,
+      false /* offline_preview_expected */, false /* previews_likely */,
+      CoinFlipHoldbackResult::kNotSet,
       base::TimeDelta::FromMilliseconds(1337) /* navigation_restart_penalty */);
 }
 
-TEST_F(PreviewsUKMObserverTest, CheckReportingForHidden) {
-  RunTest(PreviewsType::NONE, false /* lite_page_received */,
+TEST_F(PreviewsUKMObserverTest, PreviewsLikelySet_PreCommitDecision) {
+  RunTest(content::OFFLINE_PAGE_ON | content::NOSCRIPT_ON /* allowed_state */,
+          PreviewsType::NONE, false /* lite_page_received */,
+          false /* lite_page_redirect_received */, false /* noscript_on */,
+          false /* resource_loading_hints_on */, false /* origin_opt_out */,
+          true /* save_data_enabled */, true /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
+          base::nullopt /* navigation_restart_penalty */);
+
+  NavigateToUntrackedUrl();
+
+  ValidateUKM(false /* server_lofi_expected */,
+              false /* client_lofi_expected */, false /* lite_page_expected */,
+              false /* lite_page_redirect_expected */,
+              false /* noscript_expected */,
+              false /* resource_loading_hints_expected */,
+              0 /* opt_out_value */, false /* origin_opt_out_expected */,
+              true /* save_data_enabled_expected */,
+              true /* offline_preview_expected */, true /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
+              base::nullopt /* navigation_restart_penalty */);
+}
+
+TEST_F(PreviewsUKMObserverTest, PreviewsLikelyNotSet_PostCommitDecision) {
+  RunTest(content::NOSCRIPT_ON /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           true /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
+          base::nullopt /* navigation_restart_penalty */);
+
+  NavigateToUntrackedUrl();
+
+  ValidateUKM(false /* server_lofi_expected */,
+              false /* client_lofi_expected */, false /* lite_page_expected */,
+              false /* lite_page_redirect_expected */,
+              false /* noscript_expected */,
+              false /* resource_loading_hints_expected */,
+              0 /* opt_out_value */, false /* origin_opt_out_expected */,
+              true /* save_data_enabled_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
+              base::nullopt /* navigation_restart_penalty */);
+}
+
+TEST_F(PreviewsUKMObserverTest, PreviewsLikelyNotSet_PreviewsOff) {
+  RunTest(content::PREVIEWS_OFF /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
+          false /* lite_page_redirect_received */, false /* noscript_on */,
+          false /* resource_loading_hints_on */, false /* origin_opt_out */,
+          true /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
+          base::nullopt /* navigation_restart_penalty */);
+
+  NavigateToUntrackedUrl();
+
+  ValidateUKM(false /* server_lofi_expected */,
+              false /* client_lofi_expected */, false /* lite_page_expected */,
+              false /* lite_page_redirect_expected */,
+              false /* noscript_expected */,
+              false /* resource_loading_hints_expected */,
+              0 /* opt_out_value */, false /* origin_opt_out_expected */,
+              true /* save_data_enabled_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
+              base::nullopt /* navigation_restart_penalty */);
+}
+
+TEST_F(PreviewsUKMObserverTest, CoinFlipResult_Holdback) {
+  RunTest(content::OFFLINE_PAGE_ON /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
+          false /* lite_page_redirect_received */, false /* noscript_on */,
+          false /* resource_loading_hints_on */, false /* origin_opt_out */,
+          true /* save_data_enabled */, true /* is_offline_preview */,
+          CoinFlipHoldbackResult::kHoldback,
+          base::nullopt /* navigation_restart_penalty */);
+
+  NavigateToUntrackedUrl();
+
+  ValidateUKM(false /* server_lofi_expected */,
+              false /* client_lofi_expected */, false /* lite_page_expected */,
+              false /* lite_page_redirect_expected */,
+              false /* noscript_expected */,
+              false /* resource_loading_hints_expected */,
+              0 /* opt_out_value */, false /* origin_opt_out_expected */,
+              true /* save_data_enabled_expected */,
+              true /* offline_preview_expected */, true /* previews_likely */,
+              CoinFlipHoldbackResult::kHoldback,
+              base::nullopt /* navigation_restart_penalty */);
+}
+
+TEST_F(PreviewsUKMObserverTest, CoinFlipResult_Allowed) {
+  RunTest(content::OFFLINE_PAGE_ON /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
+          false /* lite_page_redirect_received */, false /* noscript_on */,
+          false /* resource_loading_hints_on */, false /* origin_opt_out */,
+          true /* save_data_enabled */, true /* is_offline_preview */,
+          CoinFlipHoldbackResult::kAllowed,
+          base::nullopt /* navigation_restart_penalty */);
+
+  NavigateToUntrackedUrl();
+
+  ValidateUKM(false /* server_lofi_expected */,
+              false /* client_lofi_expected */, false /* lite_page_expected */,
+              false /* lite_page_redirect_expected */,
+              false /* noscript_expected */,
+              false /* resource_loading_hints_expected */,
+              0 /* opt_out_value */, false /* origin_opt_out_expected */,
+              true /* save_data_enabled_expected */,
+              true /* offline_preview_expected */, true /* previews_likely */,
+              CoinFlipHoldbackResult::kAllowed,
+              base::nullopt /* navigation_restart_penalty */);
+}
+
+TEST_F(PreviewsUKMObserverTest, CheckReportingForHidden) {
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
+          false /* lite_page_redirect_received */, false /* noscript_on */,
+          false /* resource_loading_hints_on */, false /* origin_opt_out */,
+          true /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   web_contents()->WasHidden();
@@ -1125,15 +1349,18 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               true /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
 TEST_F(PreviewsUKMObserverTest, CheckReportingForFlushMetrics) {
-  RunTest(PreviewsType::NONE, false /* lite_page_received */,
+  RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE,
+          false /* lite_page_received */,
           false /* lite_page_redirect_received */, false /* noscript_on */,
           false /* resource_loading_hints_on */, false /* origin_opt_out */,
           true /* save_data_enabled */, false /* is_offline_preview */,
+          CoinFlipHoldbackResult::kNotSet,
           base::nullopt /* navigation_restart_penalty */);
 
   SimulateAppEnterBackground();
@@ -1145,7 +1372,8 @@
               false /* resource_loading_hints_expected */,
               0 /* opt_out_value */, false /* origin_opt_out_expected */,
               true /* save_data_enabled_expected */,
-              false /* offline_preview_expected */,
+              false /* offline_preview_expected */, false /* previews_likely */,
+              CoinFlipHoldbackResult::kNotSet,
               base::nullopt /* navigation_restart_penalty */);
 }
 
@@ -1157,10 +1385,12 @@
       continue;
 
     base::HistogramTester tester;
-    RunTest(type, false /* lite_page_received */,
+    RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, type,
+            false /* lite_page_received */,
             false /* lite_page_redirect_received */, false /* noscript_on */,
             false /* resource_loading_hints_on */, false /* origin_opt_out */,
             false /* save_data_enabled */, false /* is_offline_preview */,
+            CoinFlipHoldbackResult::kNotSet,
             base::nullopt /* navigation_restart_penalty */);
 
     NavigateToUntrackedUrl();
diff --git a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
index 7d774c4..66b652ee 100644
--- a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
+++ b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
@@ -97,6 +97,7 @@
           WebFeature::kLinkRelPrerender,
           WebFeature::kAdClickNavigation,
           WebFeature::kDownloadInSandboxWithoutUserGesture,
+          WebFeature::kV8HTMLVideoElement_RequestPictureInPicture_Method,
       }));
   return *opt_in_features;
 }
diff --git a/chrome/browser/payments/payment_handler_permission_context.cc b/chrome/browser/payments/payment_handler_permission_context.cc
index 7c93e40..e1c97e8 100644
--- a/chrome/browser/payments/payment_handler_permission_context.cc
+++ b/chrome/browser/payments/payment_handler_permission_context.cc
@@ -28,7 +28,7 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   // The user should never be prompted to authorize payment handler.
   NOTREACHED();
 }
diff --git a/chrome/browser/payments/payment_handler_permission_context.h b/chrome/browser/payments/payment_handler_permission_context.h
index c4f428e..5ca1471 100644
--- a/chrome/browser/payments/payment_handler_permission_context.h
+++ b/chrome/browser/payments/payment_handler_permission_context.h
@@ -30,7 +30,7 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
   bool IsRestrictedToSecureOrigins() const override;
 
   DISALLOW_COPY_AND_ASSIGN(PaymentHandlerPermissionContext);
diff --git a/chrome/browser/permissions/permission_context_base.cc b/chrome/browser/permissions/permission_context_base.cc
index bede441..91ec8ab 100644
--- a/chrome/browser/permissions/permission_context_base.cc
+++ b/chrome/browser/permissions/permission_context_base.cc
@@ -116,7 +116,7 @@
     const PermissionRequestID& id,
     const GURL& requesting_frame,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   GURL requesting_origin = requesting_frame.GetOrigin();
@@ -130,8 +130,9 @@
              << " from an invalid URL: " << requesting_origin << ","
              << embedding_origin << " (" << type_name
              << " is not supported in popups)";
-    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
-                        false /* persist */, CONTENT_SETTING_BLOCK);
+    NotifyPermissionSet(id, requesting_origin, embedding_origin,
+                        std::move(callback), false /* persist */,
+                        CONTENT_SETTING_BLOCK);
     return;
   }
 
@@ -150,7 +151,7 @@
         LogPermissionBlockedMessage(web_contents,
                                     kPermissionBlockedKillSwitchMessage,
                                     content_settings_type_);
-        callback.Run(CONTENT_SETTING_BLOCK);
+        std::move(callback).Run(CONTENT_SETTING_BLOCK);
         return;
       case PermissionStatusSource::MULTIPLE_DISMISSALS:
         LogPermissionBlockedMessage(web_contents,
@@ -176,8 +177,9 @@
     // If we are under embargo, record the embargo reason for which we have
     // suppressed the prompt.
     PermissionUmaUtil::RecordEmbargoPromptSuppressionFromSource(result.source);
-    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
-                        false /* persist */, result.content_setting);
+    NotifyPermissionSet(id, requesting_origin, embedding_origin,
+                        std::move(callback), false /* persist */,
+                        result.content_setting);
     return;
   }
 
@@ -188,7 +190,7 @@
       PermissionEmbargoStatus::NOT_EMBARGOED);
 
   DecidePermission(web_contents, id, requesting_origin, embedding_origin,
-                   user_gesture, callback);
+                   user_gesture, std::move(callback));
 }
 
 void PermissionContextBase::UserMadePermissionDecision(
@@ -314,7 +316,7 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // Under permission delegation, when we display a permission prompt, the
@@ -338,11 +340,11 @@
   std::unique_ptr<PermissionRequest> request_ptr =
       std::make_unique<PermissionRequestImpl>(
           requesting_origin, content_settings_type_, user_gesture,
-          base::Bind(&PermissionContextBase::PermissionDecided,
-                     weak_factory_.GetWeakPtr(), id, requesting_origin,
-                     embedding_origin, callback),
-          base::Bind(&PermissionContextBase::CleanUpRequest,
-                     weak_factory_.GetWeakPtr(), id));
+          base::BindOnce(&PermissionContextBase::PermissionDecided,
+                         weak_factory_.GetWeakPtr(), id, requesting_origin,
+                         embedding_origin, std::move(callback)),
+          base::BindOnce(&PermissionContextBase::CleanUpRequest,
+                         weak_factory_.GetWeakPtr(), id));
   PermissionRequest* request = request_ptr.get();
 
   bool inserted =
@@ -357,7 +359,7 @@
     const PermissionRequestID& id,
     const GURL& requesting_origin,
     const GURL& embedding_origin,
-    const BrowserPermissionCallback& callback,
+    BrowserPermissionCallback callback,
     ContentSetting content_setting) {
   DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
          content_setting == CONTENT_SETTING_BLOCK ||
@@ -366,8 +368,8 @@
                              content_setting);
 
   bool persist = content_setting != CONTENT_SETTING_DEFAULT;
-  NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
-                      persist, content_setting);
+  NotifyPermissionSet(id, requesting_origin, embedding_origin,
+                      std::move(callback), persist, content_setting);
 }
 
 Profile* PermissionContextBase::profile() const {
@@ -378,7 +380,7 @@
     const PermissionRequestID& id,
     const GURL& requesting_origin,
     const GURL& embedding_origin,
-    const BrowserPermissionCallback& callback,
+    BrowserPermissionCallback callback,
     bool persist,
     ContentSetting content_setting) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -392,7 +394,7 @@
   if (content_setting == CONTENT_SETTING_DEFAULT)
     content_setting = CONTENT_SETTING_ASK;
 
-  callback.Run(content_setting);
+  std::move(callback).Run(content_setting);
 }
 
 void PermissionContextBase::CleanUpRequest(const PermissionRequestID& id) {
diff --git a/chrome/browser/permissions/permission_context_base.h b/chrome/browser/permissions/permission_context_base.h
index 450b4396..d9c7715 100644
--- a/chrome/browser/permissions/permission_context_base.h
+++ b/chrome/browser/permissions/permission_context_base.h
@@ -27,7 +27,7 @@
 class WebContents;
 }
 
-using BrowserPermissionCallback = base::Callback<void(ContentSetting)>;
+using BrowserPermissionCallback = base::OnceCallback<void(ContentSetting)>;
 
 // This base class contains common operations for granting permissions.
 // It offers the following functionality:
@@ -75,7 +75,7 @@
                                  const PermissionRequestID& id,
                                  const GURL& requesting_frame,
                                  bool user_gesture,
-                                 const BrowserPermissionCallback& callback);
+                                 BrowserPermissionCallback callback);
 
   // Returns whether the permission has been granted, denied etc.
   // |render_frame_host| may be nullptr if the call is coming from a context
@@ -115,14 +115,14 @@
                                 const GURL& requesting_origin,
                                 const GURL& embedding_origin,
                                 bool user_gesture,
-                                const BrowserPermissionCallback& callback);
+                                BrowserPermissionCallback callback);
 
   // Updates stored content setting if persist is set, updates tab indicators
   // and runs the callback to finish the request.
   virtual void NotifyPermissionSet(const PermissionRequestID& id,
                                    const GURL& requesting_origin,
                                    const GURL& embedding_origin,
-                                   const BrowserPermissionCallback& callback,
+                                   BrowserPermissionCallback callback,
                                    bool persist,
                                    ContentSetting content_setting);
 
@@ -162,7 +162,7 @@
   void PermissionDecided(const PermissionRequestID& id,
                          const GURL& requesting_origin,
                          const GURL& embedding_origin,
-                         const BrowserPermissionCallback& callback,
+                         BrowserPermissionCallback callback,
                          ContentSetting content_setting);
 
   // Called when the user has made a permission decision. This is a hook for
diff --git a/chrome/browser/permissions/permission_context_base_unittest.cc b/chrome/browser/permissions/permission_context_base_unittest.cc
index 26daecd..4c7744b 100644
--- a/chrome/browser/permissions/permission_context_base_unittest.cc
+++ b/chrome/browser/permissions/permission_context_base_unittest.cc
@@ -87,11 +87,12 @@
                          const PermissionRequestID& id,
                          const GURL& requesting_frame,
                          bool user_gesture,
-                         const BrowserPermissionCallback& callback) override {
+                         BrowserPermissionCallback callback) override {
     base::RunLoop run_loop;
     quit_closure_ = run_loop.QuitClosure();
     PermissionContextBase::RequestPermission(web_contents, id, requesting_frame,
-                                             true /* user_gesture */, callback);
+                                             true /* user_gesture */,
+                                             std::move(callback));
     run_loop.Run();
   }
 
@@ -100,10 +101,10 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override {
+                        BrowserPermissionCallback callback) override {
     PermissionContextBase::DecidePermission(web_contents, id, requesting_origin,
                                             embedding_origin, user_gesture,
-                                            callback);
+                                            std::move(callback));
     if (respond_permission_) {
       respond_permission_.Run();
       respond_permission_.Reset();
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index 7efbe09..3f612a3c 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -142,33 +142,33 @@
 }
 
 void SubscriptionCallbackWrapper(
-    const base::Callback<void(PermissionStatus)>& callback,
+    base::OnceCallback<void(PermissionStatus)> callback,
     ContentSetting content_setting) {
-  callback.Run(ContentSettingToPermissionStatus(content_setting));
+  std::move(callback).Run(ContentSettingToPermissionStatus(content_setting));
 }
 
 void PermissionStatusCallbackWrapper(
-    const base::Callback<void(PermissionStatus)>& callback,
+    base::OnceCallback<void(PermissionStatus)> callback,
     const std::vector<ContentSetting>& vector) {
   DCHECK_EQ(1ul, vector.size());
-  callback.Run(ContentSettingToPermissionStatus(vector[0]));
+  std::move(callback).Run(ContentSettingToPermissionStatus(vector.at(0)));
 }
 
 void PermissionStatusVectorCallbackWrapper(
-    const base::Callback<void(const std::vector<PermissionStatus>&)>& callback,
+    base::OnceCallback<void(const std::vector<PermissionStatus>&)> callback,
     const std::vector<ContentSetting>& content_settings) {
   std::vector<PermissionStatus> permission_statuses;
   std::transform(content_settings.begin(), content_settings.end(),
                  back_inserter(permission_statuses),
                  ContentSettingToPermissionStatus);
-  callback.Run(permission_statuses);
+  std::move(callback).Run(permission_statuses);
 }
 
-void ContentSettingCallbackWraper(
-    const base::Callback<void(ContentSetting)>& callback,
+void ContentSettingCallbackWrapper(
+    base::OnceCallback<void(ContentSetting)> callback,
     const std::vector<ContentSetting>& vector) {
   DCHECK_EQ(1ul, vector.size());
-  callback.Run(vector[0]);
+  std::move(callback).Run(vector.at(0));
 }
 
 }  // anonymous namespace
@@ -178,10 +178,10 @@
   PendingRequest(
       content::RenderFrameHost* render_frame_host,
       const std::vector<ContentSettingsType>& permissions,
-      const base::Callback<void(const std::vector<ContentSetting>&)>& callback)
+      base::OnceCallback<void(const std::vector<ContentSetting>&)> callback)
       : render_process_id_(render_frame_host->GetProcess()->GetID()),
         render_frame_id_(render_frame_host->GetRoutingID()),
-        callback_(callback),
+        callback_(std::move(callback)),
         permissions_(permissions),
         results_(permissions.size(), CONTENT_SETTING_BLOCK),
         remaining_results_(permissions.size()) {}
@@ -200,9 +200,8 @@
   int render_process_id() const { return render_process_id_; }
   int render_frame_id() const { return render_frame_id_; }
 
-  const base::Callback<void(const std::vector<ContentSetting>&)> callback()
-      const {
-    return callback_;
+  base::OnceCallback<void(const std::vector<ContentSetting>&)> TakeCallback() {
+    return std::move(callback_);
   }
 
   std::vector<ContentSettingsType> permissions() const {
@@ -214,7 +213,7 @@
  private:
   int render_process_id_;
   int render_frame_id_;
-  const base::Callback<void(const std::vector<ContentSetting>&)> callback_;
+  base::OnceCallback<void(const std::vector<ContentSetting>&)> callback_;
   std::vector<ContentSettingsType> permissions_;
   std::vector<ContentSetting> results_;
   size_t remaining_results_;
@@ -264,7 +263,7 @@
   GURL requesting_origin;
   int render_frame_id = -1;
   int render_process_id = -1;
-  base::Callback<void(ContentSetting)> callback;
+  base::RepeatingCallback<void(ContentSetting)> callback;
   ContentSetting current_value;
 };
 
@@ -373,11 +372,11 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(ContentSetting)>& callback) {
+    base::OnceCallback<void(ContentSetting)> callback) {
   return RequestPermissions(
       std::vector<ContentSettingsType>(1, content_settings_type),
       render_frame_host, requesting_origin, user_gesture,
-      base::Bind(&ContentSettingCallbackWraper, callback));
+      base::BindOnce(&ContentSettingCallbackWrapper, std::move(callback)));
 }
 
 int PermissionManager::RequestPermissions(
@@ -385,10 +384,10 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(const std::vector<ContentSetting>&)>& callback) {
+    base::OnceCallback<void(const std::vector<ContentSetting>&)> callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (permissions.empty()) {
-    callback.Run(std::vector<ContentSetting>());
+    std::move(callback).Run(std::vector<ContentSetting>());
     return content::PermissionController::kNoPendingOperation;
   }
 
@@ -400,19 +399,20 @@
       GetCanonicalOrigin(requesting_origin, embedding_origin);
 
   int request_id = pending_requests_.Add(std::make_unique<PendingRequest>(
-      render_frame_host, permissions, callback));
+      render_frame_host, permissions, std::move(callback)));
 
   const PermissionRequestID request(render_frame_host, request_id);
 
   for (size_t i = 0; i < permissions.size(); ++i) {
     const ContentSettingsType permission = permissions[i];
 
-    auto callback =
+    auto response_callback =
         std::make_unique<PermissionResponseCallback>(this, request_id, i);
     auto status = GetPermissionOverrideForDevTools(canonical_requesting_origin,
                                                    permission);
     if (status != CONTENT_SETTING_DEFAULT) {
-      callback->OnPermissionsRequestResponseStatus(CONTENT_SETTING_ALLOW);
+      response_callback->OnPermissionsRequestResponseStatus(
+          CONTENT_SETTING_ALLOW);
       continue;
     }
 
@@ -421,9 +421,9 @@
 
     context->RequestPermission(
         web_contents, request, canonical_requesting_origin, user_gesture,
-        base::Bind(
+        base::BindOnce(
             &PermissionResponseCallback::OnPermissionsRequestResponseStatus,
-            base::Passed(&callback)));
+            std::move(response_callback)));
   }
 
   // The request might have been resolved already.
@@ -464,13 +464,13 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(PermissionStatus)>& callback) {
+    base::OnceCallback<void(PermissionStatus)> callback) {
   ContentSettingsType content_settings_type =
       PermissionTypeToContentSetting(permission);
   return RequestPermissions(
       std::vector<ContentSettingsType>(1, content_settings_type),
       render_frame_host, requesting_origin, user_gesture,
-      base::Bind(&PermissionStatusCallbackWrapper, callback));
+      base::BindOnce(&PermissionStatusCallbackWrapper, std::move(callback)));
 }
 
 int PermissionManager::RequestPermissions(
@@ -478,8 +478,7 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(const std::vector<PermissionStatus>&)>&
-        callback) {
+    base::OnceCallback<void(const std::vector<PermissionStatus>&)> callback) {
   std::vector<ContentSettingsType> content_settings_types;
   std::transform(permissions.begin(), permissions.end(),
                  back_inserter(content_settings_types),
@@ -487,7 +486,8 @@
   return RequestPermissions(
       content_settings_types, render_frame_host, requesting_origin,
       user_gesture,
-      base::Bind(&PermissionStatusVectorCallbackWrapper, callback));
+      base::BindOnce(&PermissionStatusVectorCallbackWrapper,
+                     std::move(callback)));
 }
 
 PermissionContextBase* PermissionManager::GetPermissionContext(
@@ -509,7 +509,7 @@
   if (!pending_request->IsComplete())
     return;
 
-  pending_request->callback().Run(pending_request->results());
+  pending_request->TakeCallback().Run(pending_request->results());
   pending_requests_.Remove(request_id);
 }
 
@@ -576,7 +576,7 @@
     PermissionType permission,
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
-    const base::Callback<void(PermissionStatus)>& callback) {
+    base::RepeatingCallback<void(PermissionStatus)> callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (subscriptions_.IsEmpty())
     HostContentSettingsMapFactory::GetForProfile(profile_)->AddObserver(this);
@@ -608,7 +608,8 @@
   subscription->permission = content_type;
   subscription->requesting_origin =
       GetCanonicalOrigin(requesting_origin, embedding_origin);
-  subscription->callback = base::Bind(&SubscriptionCallbackWrapper, callback);
+  subscription->callback =
+      base::BindRepeating(&SubscriptionCallbackWrapper, std::move(callback));
 
   return subscriptions_.Add(std::move(subscription));
 }
@@ -635,7 +636,8 @@
     ContentSettingsType content_type,
     const std::string& resource_identifier) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  std::list<base::Closure> callbacks;
+  std::vector<base::OnceClosure> callbacks;
+  callbacks.reserve(subscriptions_.size());
 
   for (SubscriptionsMap::iterator iter(&subscriptions_);
        !iter.IsAtEnd(); iter.Advance()) {
@@ -681,11 +683,11 @@
 
     // Add the callback to |callbacks| which will be run after the loop to
     // prevent re-entrance issues.
-    callbacks.push_back(base::Bind(subscription->callback, new_value));
+    callbacks.push_back(base::BindOnce(subscription->callback, new_value));
   }
 
-  for (const auto& callback : callbacks)
-    callback.Run();
+  for (auto& callback : callbacks)
+    std::move(callback).Run();
 }
 
 PermissionResult PermissionManager::GetPermissionStatusHelper(
diff --git a/chrome/browser/permissions/permission_manager.h b/chrome/browser/permissions/permission_manager.h
index f907ae4f1..39ab8575 100644
--- a/chrome/browser/permissions/permission_manager.h
+++ b/chrome/browser/permissions/permission_manager.h
@@ -53,13 +53,13 @@
                         content::RenderFrameHost* render_frame_host,
                         const GURL& requesting_origin,
                         bool user_gesture,
-                        const base::Callback<void(ContentSetting)>& callback);
+                        base::OnceCallback<void(ContentSetting)> callback);
   int RequestPermissions(
       const std::vector<ContentSettingsType>& permissions,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<void(const std::vector<ContentSetting>&)>& callback);
+      base::OnceCallback<void(const std::vector<ContentSetting>&)> callback);
 
   PermissionResult GetPermissionStatus(ContentSettingsType permission,
                                        const GURL& requesting_origin,
@@ -77,20 +77,19 @@
       const GURL& requesting_origin);
 
   // content::PermissionControllerDelegate implementation.
-  int RequestPermission(
-      content::PermissionType permission,
-      content::RenderFrameHost* render_frame_host,
-      const GURL& requesting_origin,
-      bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
-      override;
+  int RequestPermission(content::PermissionType permission,
+                        content::RenderFrameHost* render_frame_host,
+                        const GURL& requesting_origin,
+                        bool user_gesture,
+                        base::OnceCallback<void(blink::mojom::PermissionStatus)>
+                            callback) override;
   int RequestPermissions(
       const std::vector<content::PermissionType>& permissions,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<
-          void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
+      base::OnceCallback<
+          void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
       override;
   void ResetPermission(content::PermissionType permission,
                        const GURL& requesting_origin,
@@ -107,7 +106,7 @@
       content::PermissionType permission,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
+      base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
       override;
   void UnsubscribePermissionStatusChange(int subscription_id) override;
 
diff --git a/chrome/browser/permissions/permission_request_impl.cc b/chrome/browser/permissions/permission_request_impl.cc
index d4a744b..3eff821f 100644
--- a/chrome/browser/permissions/permission_request_impl.cc
+++ b/chrome/browser/permissions/permission_request_impl.cc
@@ -23,13 +23,13 @@
     const GURL& request_origin,
     ContentSettingsType content_settings_type,
     bool has_gesture,
-    const PermissionDecidedCallback& permission_decided_callback,
-    const base::Closure delete_callback)
+    PermissionDecidedCallback permission_decided_callback,
+    base::OnceClosure delete_callback)
     : request_origin_(request_origin),
       content_settings_type_(content_settings_type),
       has_gesture_(has_gesture),
-      permission_decided_callback_(permission_decided_callback),
-      delete_callback_(delete_callback),
+      permission_decided_callback_(std::move(permission_decided_callback)),
+      delete_callback_(std::move(delete_callback)),
       is_finished_(false) {}
 
 PermissionRequestImpl::~PermissionRequestImpl() {
@@ -175,20 +175,20 @@
 }
 
 void PermissionRequestImpl::PermissionGranted() {
-  permission_decided_callback_.Run(CONTENT_SETTING_ALLOW);
+  std::move(permission_decided_callback_).Run(CONTENT_SETTING_ALLOW);
 }
 
 void PermissionRequestImpl::PermissionDenied() {
-  permission_decided_callback_.Run(CONTENT_SETTING_BLOCK);
+  std::move(permission_decided_callback_).Run(CONTENT_SETTING_BLOCK);
 }
 
 void PermissionRequestImpl::Cancelled() {
-  permission_decided_callback_.Run(CONTENT_SETTING_DEFAULT);
+  std::move(permission_decided_callback_).Run(CONTENT_SETTING_DEFAULT);
 }
 
 void PermissionRequestImpl::RequestFinished() {
   is_finished_ = true;
-  delete_callback_.Run();
+  std::move(delete_callback_).Run();
 }
 
 PermissionRequestType PermissionRequestImpl::GetPermissionRequestType()
diff --git a/chrome/browser/permissions/permission_request_impl.h b/chrome/browser/permissions/permission_request_impl.h
index aa7e4e1..b991ff64 100644
--- a/chrome/browser/permissions/permission_request_impl.h
+++ b/chrome/browser/permissions/permission_request_impl.h
@@ -19,14 +19,13 @@
 // is executed.
 class PermissionRequestImpl : public PermissionRequest {
  public:
-  using PermissionDecidedCallback = base::Callback<void(ContentSetting)>;
+  using PermissionDecidedCallback = base::OnceCallback<void(ContentSetting)>;
 
-  PermissionRequestImpl(
-      const GURL& request_origin,
-      ContentSettingsType content_settings_type,
-      bool has_gesture,
-      const PermissionDecidedCallback& permission_decided_callback,
-      const base::Closure delete_callback);
+  PermissionRequestImpl(const GURL& request_origin,
+                        ContentSettingsType content_settings_type,
+                        bool has_gesture,
+                        PermissionDecidedCallback permission_decided_callback,
+                        base::OnceClosure delete_callback);
 
   ~PermissionRequestImpl() override;
 
@@ -51,11 +50,11 @@
   bool has_gesture_;
 
   // Called once a decision is made about the permission.
-  const PermissionDecidedCallback permission_decided_callback_;
+  PermissionDecidedCallback permission_decided_callback_;
 
   // Called when the request is no longer in use so it can be deleted by the
   // caller.
-  const base::Closure delete_callback_;
+  base::OnceClosure delete_callback_;
   bool is_finished_;
 
   DISALLOW_COPY_AND_ASSIGN(PermissionRequestImpl);
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
index c5e035d..952b2fb5 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -763,9 +763,16 @@
   EXPECT_TRUE(in_picture_in_picture);
 
   EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible());
-  EXPECT_FALSE(
-      overlay_window->controls_parent_view_for_testing()->layer()->visible());
   EXPECT_TRUE(overlay_window->video_layer_for_testing()->visible());
+  EXPECT_FALSE(overlay_window->previous_track_controls_view_for_testing()
+                   ->layer()
+                   ->visible());
+  EXPECT_FALSE(overlay_window->play_pause_controls_view_for_testing()
+                   ->layer()
+                   ->visible());
+  EXPECT_FALSE(overlay_window->next_track_controls_view_for_testing()
+                   ->layer()
+                   ->visible());
 }
 
 // Tests that changing video src to media stream when video is in
@@ -795,9 +802,16 @@
   EXPECT_TRUE(in_picture_in_picture);
 
   EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible());
-  EXPECT_FALSE(
-      overlay_window->controls_parent_view_for_testing()->layer()->visible());
   EXPECT_TRUE(overlay_window->video_layer_for_testing()->visible());
+  EXPECT_FALSE(overlay_window->previous_track_controls_view_for_testing()
+                   ->layer()
+                   ->visible());
+  EXPECT_FALSE(overlay_window->play_pause_controls_view_for_testing()
+                   ->layer()
+                   ->visible());
+  EXPECT_FALSE(overlay_window->next_track_controls_view_for_testing()
+                   ->layer()
+                   ->visible());
 }
 
 // Tests that we can enter Picture-in-Picture when a video is not preloaded,
@@ -1510,24 +1524,14 @@
   // The relative center point of the window.
   gfx::Point center(bottom_right_bounds.width() / 2,
                     bottom_right_bounds.height() / 2);
-  gfx::Point back_to_tab_button_position =
-      overlay_window_views->back_to_tab_image_position_for_testing();
   gfx::Point close_button_position =
       overlay_window_views->close_image_position_for_testing();
-  gfx::Point mute_button_position =
-      overlay_window_views->mute_image_position_for_testing();
   gfx::Point resize_button_position =
       overlay_window_views->resize_handle_position_for_testing();
 
-  // The back-to-tab button should be in the bottom right corner.
-  EXPECT_LT(center.x(), back_to_tab_button_position.x());
-  EXPECT_LT(center.y(), back_to_tab_button_position.y());
   // The close button should be in the top right corner.
   EXPECT_LT(center.x(), close_button_position.x());
   EXPECT_GT(center.y(), close_button_position.y());
-  // The mute button should be in the bottom left corner.
-  EXPECT_GT(center.x(), mute_button_position.x());
-  EXPECT_LT(center.y(), mute_button_position.y());
   // The resize button should be in the top left corner.
   EXPECT_GT(center.x(), resize_button_position.x());
   EXPECT_GT(center.y(), resize_button_position.y());
@@ -1539,24 +1543,14 @@
                                bottom_right_bounds.width(),
                                bottom_right_bounds.height());
   overlay_window_views->SetBounds(bottom_left_bounds);
-  back_to_tab_button_position =
-      overlay_window_views->back_to_tab_image_position_for_testing();
   close_button_position =
       overlay_window_views->close_image_position_for_testing();
-  mute_button_position =
-      overlay_window_views->mute_image_position_for_testing();
   resize_button_position =
       overlay_window_views->resize_handle_position_for_testing();
 
-  // The back-to-tab button should be in the bottom right corner.
-  EXPECT_LT(center.x(), back_to_tab_button_position.x());
-  EXPECT_LT(center.y(), back_to_tab_button_position.y());
   // The close button should be in the top left corner.
   EXPECT_GT(center.x(), close_button_position.x());
   EXPECT_GT(center.y(), close_button_position.y());
-  // The mute button should be in the bottom left corner.
-  EXPECT_GT(center.x(), mute_button_position.x());
-  EXPECT_LT(center.y(), mute_button_position.y());
   // The resize button should be in the top right corner.
   EXPECT_LT(center.x(), resize_button_position.x());
   EXPECT_GT(center.y(), resize_button_position.y());
@@ -1568,24 +1562,14 @@
                              bottom_right_bounds.width(),
                              bottom_right_bounds.height());
   overlay_window_views->SetBounds(top_right_bounds);
-  back_to_tab_button_position =
-      overlay_window_views->back_to_tab_image_position_for_testing();
   close_button_position =
       overlay_window_views->close_image_position_for_testing();
-  mute_button_position =
-      overlay_window_views->mute_image_position_for_testing();
   resize_button_position =
       overlay_window_views->resize_handle_position_for_testing();
 
-  // The back-to-tab button should be in bottom right corner.
-  EXPECT_LT(center.x(), back_to_tab_button_position.x());
-  EXPECT_LT(center.y(), back_to_tab_button_position.y());
   // The close button should be in the top right corner.
   EXPECT_LT(center.x(), close_button_position.x());
   EXPECT_GT(center.y(), close_button_position.y());
-  // The mute button should be in the top left corner.
-  EXPECT_GT(center.x(), mute_button_position.x());
-  EXPECT_GT(center.y(), mute_button_position.y());
   // The resize button should be in the bottom left corner.
   EXPECT_GT(center.x(), resize_button_position.x());
   EXPECT_LT(center.y(), resize_button_position.y());
@@ -1596,24 +1580,14 @@
   gfx::Rect top_left_bounds(0, 0, bottom_right_bounds.width(),
                             bottom_right_bounds.height());
   overlay_window_views->SetBounds(top_left_bounds);
-  back_to_tab_button_position =
-      overlay_window_views->back_to_tab_image_position_for_testing();
   close_button_position =
       overlay_window_views->close_image_position_for_testing();
-  mute_button_position =
-      overlay_window_views->mute_image_position_for_testing();
   resize_button_position =
       overlay_window_views->resize_handle_position_for_testing();
 
-  // The back-to-tab button should be in the bottom left corner.
-  EXPECT_GT(center.x(), back_to_tab_button_position.x());
-  EXPECT_LT(center.y(), back_to_tab_button_position.y());
   // The close button should be in the top right corner.
   EXPECT_LT(center.x(), close_button_position.x());
   EXPECT_GT(center.y(), close_button_position.y());
-  // The mute button should be in the top left corner.
-  EXPECT_GT(center.x(), mute_button_position.x());
-  EXPECT_GT(center.y(), mute_button_position.y());
   // The resize button should be in the bottom right corner.
   EXPECT_LT(center.x(), resize_button_position.x());
   EXPECT_LT(center.y(), resize_button_position.y());
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc
index ced4a71..7749b51 100644
--- a/chrome/browser/policy/chrome_browser_policy_connector.cc
+++ b/chrome/browser/policy/chrome_browser_policy_connector.cc
@@ -104,11 +104,6 @@
       kServiceInitializationStartupDelay);
 
   InitInternal(local_state, std::move(device_management_service));
-
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
-  machine_level_user_cloud_policy_controller_->Init(local_state,
-                                                    url_loader_factory);
-#endif
 }
 
 bool ChromeBrowserPolicyConnector::IsEnterpriseManaged() const {
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 018ea85..c076f58 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -611,6 +611,9 @@
   { key::kStickyKeysEnabled,
     ash::prefs::kAccessibilityStickyKeysEnabled,
     base::Value::Type::BOOLEAN },
+  { key::kDockedMagnifierEnabled,
+    ash::prefs::kDockedMagnifierEnabled,
+    base::Value::Type::BOOLEAN },
   { key::kDeviceLoginScreenDefaultLargeCursorEnabled,
     nullptr,
     base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 38cd08d..a49978e 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -2237,6 +2237,31 @@
   EXPECT_FALSE(service->GetInstalledExtension(kGoodCrxId));
 }
 
+/// Ensure that when INSTALLATION_REMOVED is set
+// that blacklisted extensions are removed from the device.
+IN_PROC_BROWSER_TEST_F(PolicyTest, ExtensionInstallRemovedPolicy) {
+  EXPECT_TRUE(InstallExtension(kGoodCrxName));
+
+  extensions::ExtensionService* service = extension_service();
+  EXPECT_TRUE(service->GetInstalledExtension(kGoodCrxId));
+
+  // Should uninstall good_v1.crx.
+  base::DictionaryValue dict_value;
+  dict_value.SetString(std::string(kGoodCrxId) + "." +
+                           extensions::schema_constants::kInstallationMode,
+                       extensions::schema_constants::kRemoved);
+  PolicyMap policies;
+  policies.Set(key::kExtensionSettings, POLICY_LEVEL_MANDATORY,
+               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
+               dict_value.CreateDeepCopy(), nullptr);
+  extensions::TestExtensionRegistryObserver observer(
+      extensions::ExtensionRegistry::Get(browser()->profile()));
+  UpdateProviderPolicy(policies);
+  observer.WaitForExtensionUnloaded();
+
+  EXPECT_FALSE(service->GetInstalledExtension(kGoodCrxId));
+}
+
 // Ensure that bookmark apps are not blocked by the ExtensionAllowedTypes
 // policy.
 IN_PROC_BROWSER_TEST_F(PolicyTest, ExtensionAllowedTypes_BookmarkApp) {
@@ -3978,6 +4003,32 @@
   EXPECT_FALSE(accessibility_manager->IsStickyKeysEnabled());
 }
 
+IN_PROC_BROWSER_TEST_F(PolicyTest, DockedMagnifierEnabled) {
+  // Verifies that the docked magnifier accessibility feature can be
+  // controlled through policy.
+  chromeos::MagnificationManager* magnification_manager =
+      chromeos::MagnificationManager::Get();
+
+  // Verify that the docked magnifier is initially disabled
+  EXPECT_FALSE(magnification_manager->IsDockedMagnifierEnabled());
+
+  // Manually enable the docked magnifier.
+  magnification_manager->SetDockedMagnifierEnabled(true);
+  EXPECT_TRUE(magnification_manager->IsDockedMagnifierEnabled());
+
+  // Verify that policy overrides the manual setting.
+  PolicyMap policies;
+  policies.Set(key::kDockedMagnifierEnabled, POLICY_LEVEL_MANDATORY,
+               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
+               std::make_unique<base::Value>(false), nullptr);
+  UpdateProviderPolicy(policies);
+  EXPECT_FALSE(magnification_manager->IsDockedMagnifierEnabled());
+
+  // Verify that the docked magnifier cannot be enabled manually anymore.
+  magnification_manager->SetDockedMagnifierEnabled(true);
+  EXPECT_FALSE(magnification_manager->IsDockedMagnifierEnabled());
+}
+
 IN_PROC_BROWSER_TEST_F(PolicyTest, VirtualKeyboardEnabled) {
   auto* keyboard_client = ChromeKeyboardControllerClient::Get();
   ASSERT_TRUE(keyboard_client);
diff --git a/chrome/browser/previews/previews_content_util.cc b/chrome/browser/previews/previews_content_util.cc
index 9643b45..1261c97b 100644
--- a/chrome/browser/previews/previews_content_util.cc
+++ b/chrome/browser/previews/previews_content_util.cc
@@ -434,14 +434,6 @@
   return content::PREVIEWS_OFF;
 }
 
-namespace {
-// This bit mask is all the preview types we should potentially holdback on
-// before commit.
-content::PreviewsState kPreCommitPreviews =
-    content::SERVER_LOFI_ON | content::SERVER_LITE_PAGE_ON |
-    content::OFFLINE_PAGE_ON | content::LITE_PAGE_REDIRECT_ON;
-}  // namespace
-
 content::PreviewsState MaybeCoinFlipHoldbackBeforeCommit(
     content::PreviewsState initial_state,
     content::NavigationHandle* navigation_handle) {
diff --git a/chrome/browser/previews/previews_content_util.h b/chrome/browser/previews/previews_content_util.h
index aac90612..5a93999 100644
--- a/chrome/browser/previews/previews_content_util.h
+++ b/chrome/browser/previews/previews_content_util.h
@@ -14,6 +14,12 @@
 
 namespace previews {
 
+// This bit mask is all the preview types that are fully decided
+// before commit.
+static const content::PreviewsState kPreCommitPreviews =
+    content::SERVER_LOFI_ON | content::SERVER_LITE_PAGE_ON |
+    content::OFFLINE_PAGE_ON | content::LITE_PAGE_REDIRECT_ON;
+
 // Returns whether |previews_state| has any enabled previews.
 bool HasEnabledPreviews(content::PreviewsState previews_state);
 
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 7b8ae58..f9e5b1fe 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -45,6 +45,7 @@
 #include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"
 #include "chrome/browser/ssl/chrome_ssl_host_state_delegate_factory.h"
 #include "chrome/browser/themes/theme_service.h"
+#include "chrome/browser/transition_manager/full_browser_transition_manager.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_constants.h"
@@ -163,6 +164,8 @@
   // we have to instantiate OffTheRecordProfileIOData::Handle here after a ctor.
   InitIoData();
 
+  FullBrowserTransitionManager::Get()->OnProfileCreated(this);
+
   BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
       this);
 
@@ -218,6 +221,8 @@
   GetDefaultStoragePartition(this)->GetNetworkContext()->ClearHostCache(
       nullptr, network::mojom::NetworkContext::ClearHostCacheCallback());
 
+  FullBrowserTransitionManager::Get()->OnProfileDestroyed(this);
+
   // The SimpleDependencyManager should always be passed after the
   // BrowserContextDependencyManager. This is because the KeyedService instances
   // in the BrowserContextDependencyManager's dependency graph can depend on the
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc
index 9e0edb5..0ba3a31 100644
--- a/chrome/browser/push_messaging/push_messaging_service_impl.cc
+++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -122,10 +122,10 @@
 }
 
 void UnregisterCallbackToClosure(
-    const base::Closure& closure,
+    base::OnceClosure closure,
     content::mojom::PushUnregistrationStatus status) {
-  DCHECK(!closure.is_null());
-  closure.Run();
+  DCHECK(closure);
+  std::move(closure).Run();
 }
 
 }  // namespace
@@ -361,9 +361,8 @@
             ? -1 /* kInvalidServiceWorkerRegistrationId */
             : app_identifier.service_worker_registration_id(),
         app_id, message.sender_id,
-        base::Bind(&UnregisterCallbackToClosure,
-                   base::AdaptCallbackForRepeating(
-                       completion_closure_runner.Release())));
+        base::BindOnce(&UnregisterCallbackToClosure,
+                       completion_closure_runner.Release()));
   }
 }
 
@@ -430,7 +429,7 @@
     int render_frame_id,
     const content::PushSubscriptionOptions& options,
     bool user_gesture,
-    const RegisterCallback& callback) {
+    RegisterCallback callback) {
   PushMessagingAppIdentifier app_identifier =
       PushMessagingAppIdentifier::FindByServiceWorker(
           profile_, requesting_origin, service_worker_registration_id);
@@ -445,7 +444,8 @@
   if (push_subscription_count_ + pending_push_subscription_count_ >=
       kMaxRegistrations) {
     SubscribeEndWithError(
-        callback, content::mojom::PushRegistrationStatus::LIMIT_REACHED);
+        std::move(callback),
+        content::mojom::PushRegistrationStatus::LIMIT_REACHED);
     return;
   }
 
@@ -462,7 +462,8 @@
         kSilentPushUnsupportedMessage);
 
     SubscribeEndWithError(
-        callback, content::mojom::PushRegistrationStatus::PERMISSION_DENIED);
+        std::move(callback),
+        content::mojom::PushRegistrationStatus::PERMISSION_DENIED);
     return;
   }
 
@@ -470,16 +471,16 @@
   PermissionManager::Get(profile_)->RequestPermission(
       CONTENT_SETTINGS_TYPE_NOTIFICATIONS, web_contents->GetMainFrame(),
       requesting_origin, user_gesture,
-      base::Bind(&PushMessagingServiceImpl::DoSubscribe,
-                 weak_factory_.GetWeakPtr(), app_identifier, options,
-                 callback));
+      base::BindOnce(&PushMessagingServiceImpl::DoSubscribe,
+                     weak_factory_.GetWeakPtr(), app_identifier, options,
+                     std::move(callback)));
 }
 
 void PushMessagingServiceImpl::SubscribeFromWorker(
     const GURL& requesting_origin,
     int64_t service_worker_registration_id,
     const content::PushSubscriptionOptions& options,
-    const RegisterCallback& register_callback) {
+    RegisterCallback register_callback) {
   PushMessagingAppIdentifier app_identifier =
       PushMessagingAppIdentifier::FindByServiceWorker(
           profile_, requesting_origin, service_worker_registration_id);
@@ -494,7 +495,7 @@
   if (push_subscription_count_ + pending_push_subscription_count_ >=
       kMaxRegistrations) {
     SubscribeEndWithError(
-        register_callback,
+        std::move(register_callback),
         content::mojom::PushRegistrationStatus::LIMIT_REACHED);
     return;
   }
@@ -504,12 +505,12 @@
 
   if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
     SubscribeEndWithError(
-        register_callback,
+        std::move(register_callback),
         content::mojom::PushRegistrationStatus::PERMISSION_DENIED);
     return;
   }
 
-  DoSubscribe(app_identifier, options, register_callback,
+  DoSubscribe(app_identifier, options, std::move(register_callback),
               CONTENT_SETTING_ALLOW);
 }
 
@@ -536,11 +537,11 @@
 void PushMessagingServiceImpl::DoSubscribe(
     const PushMessagingAppIdentifier& app_identifier,
     const content::PushSubscriptionOptions& options,
-    const RegisterCallback& register_callback,
+    RegisterCallback register_callback,
     ContentSetting content_setting) {
   if (content_setting != CONTENT_SETTING_ALLOW) {
     SubscribeEndWithError(
-        register_callback,
+        std::move(register_callback),
         content::mojom::PushRegistrationStatus::PERMISSION_DENIED);
     return;
   }
@@ -549,27 +550,28 @@
 
   GetInstanceIDDriver()
       ->GetInstanceID(app_identifier.app_id())
-      ->GetToken(NormalizeSenderInfo(options.sender_info), kGCMScope,
-                 std::map<std::string, std::string>() /* options */,
-                 false /* is_lazy */,
-                 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
-                            weak_factory_.GetWeakPtr(), app_identifier,
-                            options.sender_info, register_callback));
+      ->GetToken(
+          NormalizeSenderInfo(options.sender_info), kGCMScope,
+          std::map<std::string, std::string>() /* options */,
+          false /* is_lazy */,
+          base::BindOnce(&PushMessagingServiceImpl::DidSubscribe,
+                         weak_factory_.GetWeakPtr(), app_identifier,
+                         options.sender_info, std::move(register_callback)));
 }
 
 void PushMessagingServiceImpl::SubscribeEnd(
-    const RegisterCallback& callback,
+    RegisterCallback callback,
     const std::string& subscription_id,
     const std::vector<uint8_t>& p256dh,
     const std::vector<uint8_t>& auth,
     content::mojom::PushRegistrationStatus status) {
-  callback.Run(subscription_id, p256dh, auth, status);
+  std::move(callback).Run(subscription_id, p256dh, auth, status);
 }
 
 void PushMessagingServiceImpl::SubscribeEndWithError(
-    const RegisterCallback& callback,
+    RegisterCallback callback,
     content::mojom::PushRegistrationStatus status) {
-  SubscribeEnd(callback, std::string() /* subscription_id */,
+  SubscribeEnd(std::move(callback), std::string() /* subscription_id */,
                std::vector<uint8_t>() /* p256dh */,
                std::vector<uint8_t>() /* auth */, status);
 }
@@ -577,7 +579,7 @@
 void PushMessagingServiceImpl::DidSubscribe(
     const PushMessagingAppIdentifier& app_identifier,
     const std::string& sender_id,
-    const RegisterCallback& callback,
+    RegisterCallback callback,
     const std::string& subscription_id,
     InstanceID::Result result) {
   DecreasePushSubscriptionCount(1, true /* was_pending */);
@@ -592,9 +594,10 @@
       // order to send payloads to the user.
       GetEncryptionInfoForAppId(
           app_identifier.app_id(), sender_id,
-          base::Bind(&PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo,
-                     weak_factory_.GetWeakPtr(), app_identifier, callback,
-                     subscription_id));
+          base::BindOnce(
+              &PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo,
+              weak_factory_.GetWeakPtr(), app_identifier, std::move(callback),
+              subscription_id));
       return;
     case InstanceID::INVALID_PARAMETER:
     case InstanceID::DISABLED:
@@ -610,18 +613,18 @@
       break;
   }
 
-  SubscribeEndWithError(callback, status);
+  SubscribeEndWithError(std::move(callback), status);
 }
 
 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo(
     const PushMessagingAppIdentifier& app_identifier,
-    const RegisterCallback& callback,
+    RegisterCallback callback,
     const std::string& subscription_id,
     const std::string& p256dh,
     const std::string& auth_secret) {
   if (p256dh.empty()) {
     SubscribeEndWithError(
-        callback,
+        std::move(callback),
         content::mojom::PushRegistrationStatus::PUBLIC_KEY_UNAVAILABLE);
     return;
   }
@@ -631,7 +634,7 @@
   IncreasePushSubscriptionCount(1, false /* is_pending */);
 
   SubscribeEnd(
-      callback, subscription_id,
+      std::move(callback), subscription_id,
       std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
       std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()),
       content::mojom::PushRegistrationStatus::SUCCESS_FROM_PUSH_SERVICE);
@@ -704,7 +707,7 @@
     const GURL& requesting_origin,
     int64_t service_worker_registration_id,
     const std::string& sender_id,
-    const UnregisterCallback& callback) {
+    UnregisterCallback callback) {
   PushMessagingAppIdentifier app_identifier =
       PushMessagingAppIdentifier::FindByServiceWorker(
           profile_, requesting_origin, service_worker_registration_id);
@@ -712,7 +715,7 @@
   UnsubscribeInternal(
       reason, requesting_origin, service_worker_registration_id,
       app_identifier.is_null() ? std::string() : app_identifier.app_id(),
-      sender_id, callback);
+      sender_id, std::move(callback));
 }
 
 void PushMessagingServiceImpl::UnsubscribeInternal(
@@ -721,7 +724,7 @@
     int64_t service_worker_registration_id,
     const std::string& app_id,
     const std::string& sender_id,
-    const UnregisterCallback& callback) {
+    UnregisterCallback callback) {
   DCHECK(!app_id.empty() || (!origin.is_empty() &&
                              service_worker_registration_id !=
                                  -1 /* kInvalidServiceWorkerRegistrationId */))
@@ -733,25 +736,25 @@
       service_worker_registration_id ==
           -1 /* kInvalidServiceWorkerRegistrationId */) {
     // Can't clear Service Worker database.
-    DidClearPushSubscriptionId(reason, app_id, sender_id, callback);
+    DidClearPushSubscriptionId(reason, app_id, sender_id, std::move(callback));
     return;
   }
   ClearPushSubscriptionId(
       profile_, origin, service_worker_registration_id,
-      base::Bind(&PushMessagingServiceImpl::DidClearPushSubscriptionId,
-                 weak_factory_.GetWeakPtr(), reason, app_id, sender_id,
-                 callback));
+      base::BindOnce(&PushMessagingServiceImpl::DidClearPushSubscriptionId,
+                     weak_factory_.GetWeakPtr(), reason, app_id, sender_id,
+                     std::move(callback)));
 }
 
 void PushMessagingServiceImpl::DidClearPushSubscriptionId(
     content::mojom::PushUnregistrationReason reason,
     const std::string& app_id,
     const std::string& sender_id,
-    const UnregisterCallback& callback) {
+    UnregisterCallback callback) {
   if (app_id.empty()) {
     // Without an |app_id|, we can neither delete the subscription from the
     // PushMessagingAppIdentifier map, nor unsubscribe with the GCM Driver.
-    callback.Run(
+    std::move(callback).Run(
         content::mojom::PushUnregistrationStatus::SUCCESS_WAS_NOT_REGISTERED);
     return;
   }
@@ -773,7 +776,7 @@
   // messages are later received for a subscription that was locally deleted,
   // so as long as messages keep getting sent to it, the unsubscription should
   // eventually reach GCM servers even if this particular attempt fails.
-  callback.Run(
+  std::move(callback).Run(
       was_subscribed
           ? content::mojom::PushUnregistrationStatus::SUCCESS_UNREGISTERED
           : content::mojom::PushUnregistrationStatus::
@@ -786,20 +789,21 @@
 
   } else {
     auto unregister_callback =
-        base::Bind(&PushMessagingServiceImpl::DidUnregister,
-                   weak_factory_.GetWeakPtr(), was_subscribed);
+        base::BindOnce(&PushMessagingServiceImpl::DidUnregister,
+                       weak_factory_.GetWeakPtr(), was_subscribed);
 #if defined(OS_ANDROID)
     // On Android the backend is different, and requires the original sender_id.
     // UnsubscribeBecausePermissionRevoked and
     // DidDeleteServiceWorkerRegistration sometimes call us with an empty one.
     if (sender_id.empty()) {
-      unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER);
+      std::move(unregister_callback).Run(gcm::GCMClient::INVALID_PARAMETER);
     } else {
-      GetGCMDriver()->UnregisterWithSenderId(
-          app_id, NormalizeSenderInfo(sender_id), unregister_callback);
+      GetGCMDriver()->UnregisterWithSenderId(app_id,
+                                             NormalizeSenderInfo(sender_id),
+                                             std::move(unregister_callback));
     }
 #else
-    GetGCMDriver()->Unregister(app_id, unregister_callback);
+    GetGCMDriver()->Unregister(app_id, std::move(unregister_callback));
 #endif
   }
 }
@@ -965,7 +969,7 @@
 
 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked(
     const PushMessagingAppIdentifier& app_identifier,
-    const UnregisterCallback& callback,
+    UnregisterCallback callback,
     const std::string& sender_id,
     bool success,
     bool not_found) {
@@ -979,7 +983,7 @@
   UnsubscribeInternal(
       content::mojom::PushUnregistrationReason::PERMISSION_REVOKED,
       app_identifier.origin(), app_identifier.service_worker_registration_id(),
-      app_identifier.app_id(), sender_id, callback);
+      app_identifier.app_id(), sender_id, std::move(callback));
 }
 
 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting(
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.h b/chrome/browser/push_messaging/push_messaging_service_impl.h
index bbe679d..ab0a81c 100644
--- a/chrome/browser/push_messaging/push_messaging_service_impl.h
+++ b/chrome/browser/push_messaging/push_messaging_service_impl.h
@@ -88,11 +88,11 @@
                              int render_frame_id,
                              const content::PushSubscriptionOptions& options,
                              bool user_gesture,
-                             const RegisterCallback& callback) override;
+                             RegisterCallback callback) override;
   void SubscribeFromWorker(const GURL& requesting_origin,
                            int64_t service_worker_registration_id,
                            const content::PushSubscriptionOptions& options,
-                           const RegisterCallback& callback) override;
+                           RegisterCallback callback) override;
   void GetSubscriptionInfo(const GURL& origin,
                            int64_t service_worker_registration_id,
                            const std::string& sender_id,
@@ -102,7 +102,7 @@
                    const GURL& requesting_origin,
                    int64_t service_worker_registration_id,
                    const std::string& sender_id,
-                   const UnregisterCallback&) override;
+                   UnregisterCallback) override;
   bool SupportNonVisibleMessages() override;
   void DidDeleteServiceWorkerRegistration(
       const GURL& origin,
@@ -157,27 +157,27 @@
 
   void DoSubscribe(const PushMessagingAppIdentifier& app_identifier,
                    const content::PushSubscriptionOptions& options,
-                   const RegisterCallback& callback,
+                   RegisterCallback callback,
                    ContentSetting permission_status);
 
-  void SubscribeEnd(const RegisterCallback& callback,
+  void SubscribeEnd(RegisterCallback callback,
                     const std::string& subscription_id,
                     const std::vector<uint8_t>& p256dh,
                     const std::vector<uint8_t>& auth,
                     content::mojom::PushRegistrationStatus status);
 
-  void SubscribeEndWithError(const RegisterCallback& callback,
+  void SubscribeEndWithError(RegisterCallback callback,
                              content::mojom::PushRegistrationStatus status);
 
   void DidSubscribe(const PushMessagingAppIdentifier& app_identifier,
                     const std::string& sender_id,
-                    const RegisterCallback& callback,
+                    RegisterCallback callback,
                     const std::string& subscription_id,
                     instance_id::InstanceID::Result result);
 
   void DidSubscribeWithEncryptionInfo(
       const PushMessagingAppIdentifier& app_identifier,
-      const RegisterCallback& callback,
+      RegisterCallback callback,
       const std::string& subscription_id,
       const std::string& p256dh,
       const std::string& auth_secret);
@@ -204,13 +204,13 @@
                            int64_t service_worker_registration_id,
                            const std::string& app_id,
                            const std::string& sender_id,
-                           const UnregisterCallback& callback);
+                           UnregisterCallback callback);
 
   void DidClearPushSubscriptionId(
       content::mojom::PushUnregistrationReason reason,
       const std::string& app_id,
       const std::string& sender_id,
-      const UnregisterCallback& callback);
+      UnregisterCallback callback);
 
   void DidUnregister(bool was_subscribed, gcm::GCMClient::Result result);
   void DidDeleteID(const std::string& app_id,
@@ -223,7 +223,7 @@
 
   void UnsubscribeBecausePermissionRevoked(
       const PushMessagingAppIdentifier& app_identifier,
-      const UnregisterCallback& callback,
+      UnregisterCallback callback,
       const std::string& sender_id,
       bool success,
       bool not_found);
diff --git a/chrome/browser/renderer_preferences_util.cc b/chrome/browser/renderer_preferences_util.cc
index f5ed7f0..77a1a97f 100644
--- a/chrome/browser/renderer_preferences_util.cc
+++ b/chrome/browser/renderer_preferences_util.cc
@@ -150,7 +150,6 @@
 
 #if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_WIN)
   content::UpdateFontRendererPreferencesFromSystemSettings(prefs);
-  content::UpdateFocusRingPreferencesFromSystemSettings(prefs);
 #endif
 
 #if !defined(OS_MACOSX)
diff --git a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing.css b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing.css
index 8eb71dfc..653c4d8 100644
--- a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing.css
+++ b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing.css
@@ -100,6 +100,11 @@
   pointer-events: none;
 }
 
+.arc-time-ruler-title {
+  display: flex;
+  margin-top: 10px;
+}
+
 .hidden.arc-events-band-title::before {
   content: '\002B';
 }
diff --git a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
index 338a071..f548fd6c 100644
--- a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
+++ b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
@@ -15,11 +15,19 @@
 // Color that should never appear on UI.
 var unusedColor = '#ff0000';
 
+// Supported zooms, mcs per pixel
+var zooms = [2.5, 5.0, 10.0, 25.0, 50.0, 100.0, 250.0, 500.0, 1000.0, 2500.0];
+
+// Active zoom level, as index in |zooms|. By default 100 mcs per pixel.
+var zoomLevel = 5;
+
 /**
  * Keep in sync with ArcTracingGraphicsModel::BufferEventType
  * See chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h.
  * Describes how events should be rendered. |color| specifies color of the
- * event, |name| is used in tooltips.
+ * event, |name| is used in tooltips. |width| defines the width in case it is
+ * rendered as a line and |radius| defines the radius in case it is rendered as
+ * a circle.
  */
 var eventAttributes = {
   // kIdleIn
@@ -40,7 +48,7 @@
   // kBufferQueueReleased
   105: {color: unusedColor, name: 'buffer released'},
   // kBufferFillJank
-  106: {color: '#ff0000', name: 'buffer filling jank', width: 1.0},
+  106: {color: '#ff0000', name: 'buffer filling jank', width: 1.0, radius: 4.0},
 
   // kExoSurfaceAttach.
   200: {color: '#99ccff', name: 'surface attach'},
@@ -53,7 +61,7 @@
   // kExoReleased
   204: {color: unusedColor, name: 'released'},
   // kExoJank
-  205: {color: '#ff0000', name: 'surface attach jank', width: 1.0},
+  205: {color: '#ff0000', name: 'surface attach jank', width: 1.0, radius: 4.0},
 
   // kChromeBarrierOrder.
   300: {color: '#ff9933', name: 'barrier order'},
@@ -71,7 +79,12 @@
   // kSurfaceFlingerCompositionDone
   404: {color: unusedColor, name: 'composition done'},
   // kSurfaceFlingerCompositionJank
-  405: {color: '#ff0000', name: 'Android composition jank', width: 1.0},
+  405: {
+    color: '#ff0000',
+    name: 'Android composition jank',
+    width: 1.0,
+    radius: 4.0
+  },
 
   // kChromeOSDraw
   500: {color: '#3399ff', name: 'draw'},
@@ -84,14 +97,21 @@
   // kChromeOSSwapDone
   504: {color: '#65f441', name: 'swap done'},
   // kChromeOSJank
-  505: {color: '#ff0000', name: 'Chrome composition jank', width: 1.0},
+  505: {
+    color: '#ff0000',
+    name: 'Chrome composition jank',
+    width: 1.0,
+    radius: 4.0
+  },
 
   // kCustomEvent
-  600: {color: '#7cb342', name: 'Custom event', width: 1.0},
+  600: {color: '#7cb342', name: 'Custom event', width: 1.0, radius: 4.0},
 
   // Service events.
   // kTimeMark
   10000: {color: '#888', name: 'Time mark', width: 0.75},
+  // kTimeMarkSmall
+  10001: {color: '#888', name: 'Time mark', width: 0.15},
 };
 
 /**
@@ -182,11 +202,28 @@
  *
  * @param {number} timestamp in microseconds.
  */
-function timestempToMsText(timestamp) {
+function timestampToMsText(timestamp) {
   return (timestamp / 1000.0).toFixed(1);
 }
 
 /**
+ * Changes zoom. |delta| specifies how many zoom levels to adjust. Negative
+ * |delta| means zoom in and positive zoom out.
+ */
+function updateZoom(delta) {
+  if (!activeModel) {
+    return;
+  }
+  var newZoomLevel = zoomLevel + delta;
+  if (newZoomLevel < 0 || newZoomLevel >= zooms.length) {
+    return;
+  }
+
+  zoomLevel = newZoomLevel;
+  setGraphicBuffersModel(activeModel);
+}
+
+/**
  * Initialises UI by setting keyboard and mouse listeners to discard detailed
  * view overlay.
  */
@@ -195,6 +232,12 @@
     // Escape and Enter.
     if (event.key === 'Escape' || event.key === 'Enter') {
       discardDetailedInfo();
+    } else if (event.key === 'w') {
+      // Zoom in.
+      updateZoom(-1 /* delta */);
+    } else if (event.key === 's') {
+      // Zoom out.
+      updateZoom(1 /* delta */);
     }
   };
 
@@ -288,7 +331,7 @@
   }
 
   // Creates text element in the |svg| with provided attributes.
-  static addText(svg, x, y, fontSize, textContent, anchor) {
+  static addText(svg, x, y, fontSize, textContent, anchor, transform) {
     var text = document.createElementNS(svgNS, 'text');
     text.setAttributeNS(null, 'x', x);
     text.setAttributeNS(null, 'y', y);
@@ -297,6 +340,9 @@
     if (anchor) {
       text.setAttributeNS(null, 'text-anchor', anchor);
     }
+    if (transform) {
+      text.setAttributeNS(null, 'transform', transform);
+    }
     text.appendChild(document.createTextNode(textContent));
     svg.appendChild(text);
     return text;
@@ -465,7 +511,7 @@
       bottom: this.nextYOffset + height
     });
 
-    this.updateHeight_(height, padding);
+    this.updateHeight(height, padding);
   }
 
   /**
@@ -477,7 +523,7 @@
     SVG.addLine(
         this.svg, 0, this.nextYOffset, this.width, this.nextYOffset, '#888',
         0.25);
-    this.updateHeight_(0 /* height */, padding);
+    this.updateHeight(0 /* height */, padding);
   }
 
   /**
@@ -495,7 +541,7 @@
       bottom: this.nextYOffset + height
     });
 
-    this.updateHeight_(height, padding);
+    this.updateHeight(height, padding);
   }
 
   /**
@@ -582,7 +628,7 @@
    * @param {number} new height of the chart.
    * @param {number} padding to separate from the next band or chart.
    */
-  updateHeight_(height, padding) {
+  updateHeight(height, padding) {
     this.nextYOffset += height;
     this.height = this.nextYOffset;
     this.svg.setAttribute('height', this.height + 'px');
@@ -593,8 +639,10 @@
    * This adds events as a global events that do not belong to any band.
    *
    * @param {Events} events to add.
+   * @param {string} renderType defines how to render events, can be underfined
+   *                 for default or set to 'circle'.
    */
-  addGlobal(events) {
+  addGlobal(events, renderType) {
     var eventIndex = -1;
     while (true) {
       eventIndex = events.getNextEvent(eventIndex, 1 /* direction */);
@@ -604,8 +652,14 @@
       var event = events.events[eventIndex];
       var attributes = events.getEventAttributes(eventIndex);
       var x = this.timestampToOffset(event[1]) + this.bandOffsetX;
-      SVG.addLine(
-          this.svg, x, 0, x, this.height, attributes.color, attributes.width);
+      if (renderType == 'circle') {
+        SVG.addCircle(
+            this.svg, x, this.height / 2, attributes.radius,
+            1 /* strokeWidth */, attributes.color, 'black' /* strokeColor */);
+      } else {
+        SVG.addLine(
+            this.svg, x, 0, x, this.height, attributes.color, attributes.width);
+      }
     }
     this.globalEvents.push(events);
   }
@@ -746,12 +800,12 @@
 
     SVG.addText(
         svg, horizontalGap, yOffset, fontSize,
-        timestempToMsText(eventTimestamp) + ' ms');
+        timestampToMsText(eventTimestamp) + ' ms');
     yOffset += lineHeight;
     if (vsyncTimestamp) {
       SVG.addText(
           svg, horizontalGap, yOffset, fontSize,
-          '+' + timestempToMsText(eventTimestamp - vsyncTimestamp) +
+          '+' + timestampToMsText(eventTimestamp - vsyncTimestamp) +
               ' since last vsync ms');
       yOffset += lineHeight;
     }
@@ -785,7 +839,7 @@
 
     // Find the event under the cursor. |index| points to the current event
     // and |nextIndex| points to the next event.
-    var nextIndex = eventBand.getNextEvent(-1 /* index */, 1 /* direction */);
+    var nextIndex = eventBand.getFirstEvent();
     while (nextIndex >= 0) {
       if (eventBand.events[nextIndex][1] > eventTimestamp) {
         break;
@@ -827,8 +881,8 @@
           nextIndex < 0 ? this.maxTimestamp : eventBand.events[nextIndex][1];
       SVG.addText(
           svg, horizontalGap, yOffset, fontSize,
-          'Idle ' + timestempToMsText(startIdle) + '...' +
-              timestempToMsText(endIdle) + ' chart time ms.');
+          'Idle ' + timestampToMsText(startIdle) + '...' +
+              timestampToMsText(endIdle) + ' chart time ms.');
       yOffset += lineHeight;
     } else {
       // Show the sequence of non-idle events.
@@ -855,7 +909,7 @@
         entryToShow.text = attributes.name;
         if (entriesToShow.length > 0) {
           entriesToShow[entriesToShow.length - 1].text +=
-              ' [' + timestempToMsText(eventTimestamp - lastTimestamp) + ' ms]';
+              ' [' + timestampToMsText(eventTimestamp - lastTimestamp) + ' ms]';
         }
         entriesToShow.push(entryToShow);
         if (eventBand.isEndOfSequence(index)) {
@@ -1291,6 +1345,15 @@
   }
 
   /**
+   * Helper that finds first event. Events that pass filter are only processed.
+   *
+   * @returns {number} index of the first event or -1 in case not found.
+   */
+  getFirstEvent() {
+    return this.getNextEvent(-1 /* index */, 1 /* direction */);
+  }
+
+  /**
    * Helper that returns render attributes for the event.
    *
    * @param {number} index element index in |this.events|.
@@ -1330,7 +1393,7 @@
       return -1;
     }
     if (this.events[0][1] >= timestamp) {
-      return this.getNextEvent(-1 /* index */, 1 /* direction */);
+      return this.getFirstEvent();
     }
     if (this.events[this.events.length - 1][1] <= timestamp) {
       return this.getNextEvent(
@@ -1410,8 +1473,8 @@
   $('arc-event-bands').textContent = '';
   activeModel = model;
 
-  // Microseconds per pixel.
-  var resolution = 100.0;
+  // Microseconds per pixel. 100% zoom corresponds to 100 mcs per pixel.
+  var resolution = zooms[zoomLevel];
   var parent = $('arc-event-bands');
 
   var topBandHeight = 16;
@@ -1420,6 +1483,7 @@
   var innerBandPadding = 2;
   var innerLastBandPadding = 12;
   var chartHeight = 48;
+  var fontSize = 12;
 
   var vsyncEvents = new Events(
       model.android.global_events, 400 /* kVsync */, 400 /* kVsync */);
@@ -1459,9 +1523,10 @@
   }
 
   chromeBands.setVSync(vsyncEvents);
-  chromeBands.addGlobal(new Events(
+  var chromeJanks = new Events(
       model.chrome.global_events, 505 /* kChromeOSJank */,
-      505 /* kChromeOSJank */));
+      505 /* kChromeOSJank */);
+  chromeBands.addGlobal(chromeJanks);
 
   var androidTitle =
       new EventBandTitle(parent, 'Android graphics', 'arc-events-band-title');
@@ -1473,10 +1538,13 @@
       topBandPadding);
   // Add vsync events
   androidBands.setVSync(vsyncEvents);
-  androidBands.addGlobal(new Events(
+  var androidJanks = new Events(
       model.android.global_events, 405 /* kSurfaceFlingerCompositionJank */,
-      405 /* kSurfaceFlingerCompositionJank */));
+      405 /* kSurfaceFlingerCompositionJank */);
+  androidBands.addGlobal(androidJanks);
 
+  var allActivityJanks = [];
+  var allActivityCustomEvents = [];
   for (var i = 0; i < model.views.length; i++) {
     var view = model.views[i];
     var activityTitleText;
@@ -1511,11 +1579,98 @@
     }
     // Add vsync events
     activityBands.setVSync(vsyncEvents);
-    activityBands.addGlobal(new Events(
+
+    var activityJank = new Events(
         view.global_events, 106 /* kBufferFillJank */,
-        106 /* kBufferFillJank */));
-    activityBands.addGlobal(new Events(
-        view.global_events, 600 /* kCustomEvent */, 600 /* kCustomEvent */));
+        106 /* kBufferFillJank */);
+    activityBands.addGlobal(activityJank);
+    allActivityJanks.push(activityJank);
+
+    var activityCustomEvents = new Events(
+        view.global_events, 600 /* kCustomEvent */, 600 /* kCustomEvent */);
+    activityBands.addGlobal(activityCustomEvents);
+    allActivityCustomEvents.push(activityCustomEvents);
+  }
+
+  // Create time ruler.
+  var timeRulerEventHeight = 16;
+  var timeRulerLabelHeight = 92;
+  var timeRulerTitle =
+      new EventBandTitle(parent, '' /* title */, 'arc-time-ruler-title');
+  var timeRulerBands = new EventBands(
+      timeRulerTitle, 'arc-events-band', resolution, 0, model.duration);
+  timeRulerBands.setWidth(timeRulerBands.timestampToOffset(model.duration));
+  // Reseve space for ticks and global events.
+  timeRulerBands.updateHeight(timeRulerEventHeight, 0 /* padding */);
+
+  var kTimeMark = 10000;
+  var kTimeMarkSmall = 10001;
+  var timeEvents = [];
+  var timeTick = 0;
+  var timeTickOffset = 20 * resolution;
+  var timeTickIndex = 0;
+  while (timeTick < model.duration) {
+    if ((timeTickIndex % 10) == 0) {
+      timeEvents.push([kTimeMark, timeTick]);
+    } else {
+      timeEvents.push([kTimeMarkSmall, timeTick]);
+    }
+    timeTick += timeTickOffset;
+    ++timeTickIndex;
+  }
+  var timeMarkEvents = new Events(timeEvents, kTimeMark, kTimeMarkSmall);
+  timeRulerBands.addGlobal(timeMarkEvents);
+
+  // Add all janks
+  timeRulerBands.addGlobal(chromeJanks, 'circle' /* renderType */);
+  timeRulerBands.addGlobal(androidJanks, 'circle' /* renderType */);
+  for (var i = 0; i < allActivityJanks.length; ++i) {
+    timeRulerBands.addGlobal(allActivityJanks[i], 'circle' /* renderType */);
+  }
+  for (var i = 0; i < allActivityCustomEvents.length; ++i) {
+    timeRulerBands.addGlobal(
+        allActivityCustomEvents[i], 'circle' /* renderType */);
+  }
+  // Add vsync events
+  timeRulerBands.setVSync(vsyncEvents);
+
+  // Reseve space for labels.
+  // Add tick labels.
+  timeRulerBands.updateHeight(timeRulerLabelHeight, 0 /* padding */);
+  timeTick = 0;
+  timeTickOffset = 200 * resolution;
+  while (timeTick < model.duration) {
+    SVG.addText(
+        timeRulerBands.svg, timeRulerBands.timestampToOffset(timeTick),
+        timeRulerEventHeight, fontSize, timestampToMsText(timeTick));
+    timeTick += timeTickOffset;
+  }
+  // Add janks and custom events labels.
+  var rotationY = timeRulerEventHeight + fontSize;
+  for (var i = 0; i < timeRulerBands.globalEvents.length; ++i) {
+    var globalEvents = timeRulerBands.globalEvents[i];
+    if (globalEvents == timeMarkEvents ||
+        globalEvents == timeRulerBands.vsyncEvents) {
+      continue;
+    }
+    var index = globalEvents.getFirstEvent();
+    while (index >= 0) {
+      var event = globalEvents.events[index];
+      index = globalEvents.getNextEvent(index, 1 /* direction */);
+      var eventType = event[0];
+      var attributes = eventAttributes[eventType];
+      var text;
+      if (eventType == 600 /* kCustomEvent */) {
+        text = event[2];
+      } else {
+        text = attributes.name;
+      }
+      var x = timeRulerBands.timestampToOffset(event[1]) - fontSize;
+      SVG.addText(
+          timeRulerBands.svg, x, timeRulerEventHeight, fontSize, text,
+          'start' /* anchor */,
+          'rotate(45 ' + x + ', ' + rotationY + ')' /* transform */);
+    }
   }
 
   $('arc-graphics-tracing-save').disabled = false;
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html
index 3aa7573..fcdf9b48 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.html
+++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -14,17 +14,17 @@
   <meta http-equiv="Content-Security-Policy"
       content="$i18nRaw{contentSecurityPolicy}">
   <script src="chrome-search://local-ntp/animations.js"
-      $i18nRaw{animationsIntegrity}></script>
+      integrity="$i18n{animationsIntegrity}"></script>
   <script src="chrome-search://local-ntp/config.js"
-      $i18nRaw{configDataIntegrity}></script>
+      integrity="$i18n{configDataIntegrity}"></script>
   <script src="chrome-search://local-ntp/custom-backgrounds.js"
-      $i18nRaw{localNtpCustomBgIntegrity}></script>
+      integrity="$i18n{localNtpCustomBgIntegrity}"></script>
   <script src="chrome-search://local-ntp/doodles.js"
-      $i18nRaw{doodlesIntegrity}></script>
+      integrity="$i18n{doodlesIntegrity}"></script>
   <script src="chrome-search://local-ntp/local-ntp.js"
-      $i18nRaw{localNtpIntegrity}></script>
+      integrity="$i18n{localNtpIntegrity}"></script>
   <script src="chrome-search://local-ntp/utils.js"
-      $i18nRaw{utilsIntegrity}></script>
+      integrity="$i18n{utilsIntegrity}"></script>
   <meta charset="utf-8">
   <meta name="google" value="notranslate">
   <meta name="referrer" content="strict-origin">
@@ -207,6 +207,6 @@
   <div id="one-google-end-of-body"></div>
 
   <script defer src="chrome-search://local-ntp/voice.js"
-      $i18nRaw{localNtpVoiceIntegrity}></script>
+      integrity="$i18n{localNtpVoiceIntegrity}"></script>
 </body>
 </html>
diff --git a/chrome/browser/resources/print_preview/data/model.js b/chrome/browser/resources/print_preview/data/model.js
index 5d4b93c8..cfd4184 100644
--- a/chrome/browser/resources/print_preview/data/model.js
+++ b/chrome/browser/resources/print_preview/data/model.js
@@ -185,6 +185,245 @@
     settings: {
       type: Object,
       notify: true,
+      value: function() {
+        return {
+          pages: {
+            value: [1],
+            unavailableValue: [],
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: '',
+            updatesPreview: false,
+          },
+          copies: {
+            value: '1',
+            unavailableValue: '1',
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: '',
+            updatesPreview: false,
+          },
+          collate: {
+            value: true,
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'isCollateEnabled',
+            updatesPreview: false,
+          },
+          layout: {
+            value: false, /* portrait */
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'isLandscapeEnabled',
+            updatesPreview: true,
+          },
+          color: {
+            value: true, /* color */
+            unavailableValue: false,
+            valid: true,
+            available: false,
+            setByPolicy: false,
+            key: 'isColorEnabled',
+            updatesPreview: true,
+          },
+          mediaSize: {
+            value: {},
+            unavailableValue: {
+              width_microns: 215900,
+              height_microns: 279400,
+            },
+            valid: true,
+            available: false,
+            setByPolicy: false,
+            key: 'mediaSize',
+            updatesPreview: true,
+          },
+          margins: {
+            value: print_preview.ticket_items.MarginsTypeValue.DEFAULT,
+            unavailableValue:
+                print_preview.ticket_items.MarginsTypeValue.DEFAULT,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'marginsType',
+            updatesPreview: true,
+          },
+          customMargins: {
+            value: {},
+            unavailableValue: {},
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'customMargins',
+            updatesPreview: true,
+          },
+          dpi: {
+            value: {},
+            unavailableValue: {},
+            valid: true,
+            available: false,
+            setByPolicy: false,
+            key: 'dpi',
+            updatesPreview: false,
+          },
+          fitToPage: {
+            value: false,
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'isFitToPageEnabled',
+            updatesPreview: true,
+          },
+          scaling: {
+            value: '100',
+            unavailableValue: '100',
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'scaling',
+            updatesPreview: true,
+          },
+          customScaling: {
+            value: false,
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'customScaling',
+            updatesPreview: true,
+          },
+          duplex: {
+            value: true,
+            unavailableValue: false,
+            valid: true,
+            available: false,
+            setByPolicy: false,
+            key: 'isDuplexEnabled',
+            updatesPreview: false,
+          },
+          duplexShortEdge: {
+            value: false,
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'isDuplexShortEdge',
+            updatesPreview: false,
+          },
+          cssBackground: {
+            value: false,
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'isCssBackgroundEnabled',
+            updatesPreview: true,
+          },
+          selectionOnly: {
+            value: false,
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: '',
+            updatesPreview: true,
+          },
+          headerFooter: {
+            value: true,
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'isHeaderFooterEnabled',
+            updatesPreview: true,
+          },
+          rasterize: {
+            value: false,
+            unavailableValue: false,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: '',
+            updatesPreview: true,
+          },
+          vendorItems: {
+            value: {},
+            unavailableValue: {},
+            valid: true,
+            available: false,
+            setByPolicy: false,
+            key: 'vendorOptions',
+            updatesPreview: false,
+          },
+          pagesPerSheet: {
+            value: 1,
+            unavailableValue: 1,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: '',
+            updatesPreview: true,
+          },
+          // This does not represent a real setting value, and is used only to
+          // expose the availability of the other options settings section.
+          otherOptions: {
+            value: null,
+            unavailableValue: null,
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: '',
+            updatesPreview: false,
+          },
+          // This does not represent a real settings value, but is used to
+          // propagate the correctly formatted ranges for print tickets.
+          ranges: {
+            value: [],
+            unavailableValue: [],
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: '',
+            updatesPreview: true,
+          },
+          recentDestinations: {
+            value: [],
+            unavailableValue: [],
+            valid: true,
+            available: true,
+            setByPolicy: false,
+            key: 'recentDestinations',
+            updatesPreview: false,
+          },
+          // <if expr="chromeos">
+          pin: {
+            value: false,
+            unavailableValue: false,
+            valid: true,
+            available: false,
+            setByPolicy: false,
+            key: 'isPinEnabled',
+            updatesPreview: false,
+          },
+          pinValue: {
+            value: '',
+            unavailableValue: '',
+            valid: true,
+            available: false,
+            setByPolicy: false,
+            key: 'pinValue',
+            updatesPreview: false,
+          },
+          // </if>
+        };
+      },
     },
 
     controlsManaged: {
@@ -228,256 +467,10 @@
   /** @private {?print_preview.Cdd} */
   lastDestinationCapabilities_: null,
 
-  /** @private */
-  initializeSettings_: function() {
-    this.settings = {
-      pages: {
-        value: [1],
-        unavailableValue: [],
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: '',
-        updatesPreview: false,
-      },
-      copies: {
-        value: '1',
-        unavailableValue: '1',
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: '',
-        updatesPreview: false,
-      },
-      collate: {
-        value: true,
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'isCollateEnabled',
-        updatesPreview: false,
-      },
-      layout: {
-        value: false, /* portrait */
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'isLandscapeEnabled',
-        updatesPreview: true,
-      },
-      color: {
-        value: true, /* color */
-        unavailableValue: false,
-        valid: true,
-        available: false,
-        setByPolicy: false,
-        key: 'isColorEnabled',
-        updatesPreview: true,
-      },
-      mediaSize: {
-        value: {},
-        unavailableValue: {
-          width_microns: 215900,
-          height_microns: 279400,
-        },
-        valid: true,
-        available: false,
-        setByPolicy: false,
-        key: 'mediaSize',
-        updatesPreview: true,
-      },
-      margins: {
-        value: print_preview.ticket_items.MarginsTypeValue.DEFAULT,
-        unavailableValue: print_preview.ticket_items.MarginsTypeValue.DEFAULT,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'marginsType',
-        updatesPreview: true,
-      },
-      customMargins: {
-        value: {},
-        unavailableValue: {},
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'customMargins',
-        updatesPreview: true,
-      },
-      dpi: {
-        value: {},
-        unavailableValue: {},
-        valid: true,
-        available: false,
-        setByPolicy: false,
-        key: 'dpi',
-        updatesPreview: false,
-      },
-      fitToPage: {
-        value: false,
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'isFitToPageEnabled',
-        updatesPreview: true,
-      },
-      scaling: {
-        value: '100',
-        unavailableValue: '100',
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'scaling',
-        updatesPreview: true,
-      },
-      customScaling: {
-        value: false,
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'customScaling',
-        updatesPreview: true,
-      },
-      duplex: {
-        value: true,
-        unavailableValue: false,
-        valid: true,
-        available: false,
-        setByPolicy: false,
-        key: 'isDuplexEnabled',
-        updatesPreview: false,
-      },
-      duplexShortEdge: {
-        value: false,
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'isDuplexShortEdge',
-        updatesPreview: false,
-      },
-      cssBackground: {
-        value: false,
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'isCssBackgroundEnabled',
-        updatesPreview: true,
-      },
-      selectionOnly: {
-        value: false,
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: '',
-        updatesPreview: true,
-      },
-      headerFooter: {
-        value: true,
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'isHeaderFooterEnabled',
-        updatesPreview: true,
-      },
-      rasterize: {
-        value: false,
-        unavailableValue: false,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: '',
-        updatesPreview: true,
-      },
-      vendorItems: {
-        value: {},
-        unavailableValue: {},
-        valid: true,
-        available: false,
-        setByPolicy: false,
-        key: 'vendorOptions',
-        updatesPreview: false,
-      },
-      pagesPerSheet: {
-        value: 1,
-        unavailableValue: 1,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: '',
-        updatesPreview: true,
-      },
-      // This does not represent a real setting value, and is used only to
-      // expose the availability of the other options settings section.
-      otherOptions: {
-        value: null,
-        unavailableValue: null,
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: '',
-        updatesPreview: false,
-      },
-      // This does not represent a real settings value, but is used to
-      // propagate the correctly formatted ranges for print tickets.
-      ranges: {
-        value: [],
-        unavailableValue: [],
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: '',
-        updatesPreview: true,
-      },
-      recentDestinations: {
-        value: [],
-        unavailableValue: [],
-        valid: true,
-        available: true,
-        setByPolicy: false,
-        key: 'recentDestinations',
-        updatesPreview: false,
-      },
-      // <if expr="chromeos">
-      pin: {
-        value: false,
-        unavailableValue: false,
-        valid: true,
-        available: false,
-        setByPolicy: false,
-        key: 'isPinEnabled',
-        updatesPreview: false,
-      },
-      pinValue: {
-        value: '',
-        unavailableValue: '',
-        valid: true,
-        available: false,
-        setByPolicy: false,
-        key: 'pinValue',
-        updatesPreview: false,
-      },
-      // </if>
-    };
-  },
-
   /** @override */
   attached: function() {
     assert(!print_preview.Model.instance_);
     print_preview.Model.instance_ = this;
-    // Initialize settings after setting the instance. Setting settings earlier
-    // will cause observers to fire before setting the instance above in Polymer
-    // 1. These observers often access this object via getSettingValue(), which
-    // calls print_preview.Model.getInstance(). Some simplification may be
-    // possible after Polymer 1 is removed, see https://crbug.com/944281.
-    this.initializeSettings_();
     print_preview.Model.whenReady_.resolve();
   },
 
diff --git a/chrome/browser/resources/print_preview/data/user_info.js b/chrome/browser/resources/print_preview/data/user_info.js
index 1be3c44..f084409 100644
--- a/chrome/browser/resources/print_preview/data/user_info.js
+++ b/chrome/browser/resources/print_preview/data/user_info.js
@@ -28,10 +28,6 @@
     activeUser: {
       type: String,
       notify: true,
-      // The initialization below is needed only in Polymer 1, to allow
-      // observers to fire.
-      // TODO (rbpotter): Remove when migration to Polymer 2 is complete.
-      value: '',
     },
 
     /** @type {?print_preview.DestinationStore} */
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
index 2fc1cded..31ed72f 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
@@ -111,7 +111,7 @@
     return REBOOT_PROMPT_TYPE_OPEN_SETTINGS_PAGE;
   if (base::GetFieldTrialParamByFeatureAsBool(kRebootPromptDialogFeature,
                                               kIsModalParam,
-                                              /*default_value=*/true)) {
+                                              /*default_value=*/false)) {
     return REBOOT_PROMPT_TYPE_SHOW_MODAL_DIALOG;
   } else {
     return REBOOT_PROMPT_TYPE_SHOW_NON_MODAL_DIALOG;
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index d714cfa9..dc718d9 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -17,6 +17,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/path_service.h"
 #include "base/stl_util.h"
+#include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/post_task.h"
@@ -96,7 +97,6 @@
 const char kConfigDataFilename[] = "config.js";
 const char kDoodleScriptFilename[] = "doodle.js";
 const char kGoogleUrl[] = "https://www.google.com/";
-const char kIntegrityFormat[] = "integrity=\"sha256-%s\"";
 const char kMainHtmlFilename[] = "local-ntp.html";
 const char kNtpBackgroundCollectionScriptFilename[] =
     "ntp-background-collections.js";
@@ -104,6 +104,7 @@
 const char kOneGoogleBarScriptFilename[] = "one-google.js";
 const char kPromoScriptFilename[] = "promo.js";
 const char kSearchSuggestionsScriptFilename[] = "search-suggestions.js";
+const char kSha256[] = "sha256-";
 const char kThemeCSSFilename[] = "theme.css";
 
 const struct Resource{
@@ -920,20 +921,19 @@
     // URLDataSource, and get magical $i18n{} replacement for free.
     ui::TemplateReplacements replacements;
     replacements["animationsIntegrity"] =
-        base::StringPrintf(kIntegrityFormat, ANIMATIONS_JS_INTEGRITY);
-    replacements["configDataIntegrity"] = base::StringPrintf(
-        kIntegrityFormat,
-        search_config_provider_->config_data_integrity().c_str());
+        base::StrCat({kSha256, ANIMATIONS_JS_INTEGRITY});
+    replacements["configDataIntegrity"] = base::StrCat(
+        {kSha256, search_config_provider_->config_data_integrity()});
     replacements["localNtpCustomBgIntegrity"] =
-        base::StringPrintf(kIntegrityFormat, CUSTOM_BACKGROUNDS_JS_INTEGRITY);
+        base::StrCat({kSha256, CUSTOM_BACKGROUNDS_JS_INTEGRITY});
     replacements["doodlesIntegrity"] =
-        base::StringPrintf(kIntegrityFormat, DOODLES_JS_INTEGRITY);
+        base::StrCat({kSha256, DOODLES_JS_INTEGRITY});
     replacements["localNtpIntegrity"] =
-        base::StringPrintf(kIntegrityFormat, LOCAL_NTP_JS_INTEGRITY);
+        base::StrCat({kSha256, LOCAL_NTP_JS_INTEGRITY});
     replacements["utilsIntegrity"] =
-        base::StringPrintf(kIntegrityFormat, UTILS_JS_INTEGRITY);
+        base::StrCat({kSha256, UTILS_JS_INTEGRITY});
     replacements["localNtpVoiceIntegrity"] =
-        base::StringPrintf(kIntegrityFormat, VOICE_JS_INTEGRITY);
+        base::StrCat({kSha256, VOICE_JS_INTEGRITY});
     // TODO(dbeam): why is this needed? How does it interact with
     // URLDataSource::GetContentSecurityPolicy*() methods?
     replacements["contentSecurityPolicy"] = GetContentSecurityPolicy();
diff --git a/chrome/browser/storage/durable_storage_permission_context.cc b/chrome/browser/storage/durable_storage_permission_context.cc
index 35b2fac..4de4f98 100644
--- a/chrome/browser/storage/durable_storage_permission_context.cc
+++ b/chrome/browser/storage/durable_storage_permission_context.cc
@@ -38,7 +38,7 @@
     const GURL& requesting_origin,
     const GURL& embedding_origin,
     bool user_gesture,
-    const BrowserPermissionCallback& callback) {
+    BrowserPermissionCallback callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   DCHECK_NE(CONTENT_SETTING_ALLOW,
             GetPermissionStatus(nullptr /* render_frame_host */,
@@ -52,8 +52,9 @@
   // Durable is only allowed to be granted to the top-level origin. Embedding
   // origin is the last committed navigation origin to the web contents.
   if (requesting_origin != embedding_origin) {
-    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
-                        false /* persist */, CONTENT_SETTING_DEFAULT);
+    NotifyPermissionSet(id, requesting_origin, embedding_origin,
+                        std::move(callback), false /* persist */,
+                        CONTENT_SETTING_DEFAULT);
     return;
   }
 
@@ -65,8 +66,9 @@
   if (cookie_settings->IsCookieSessionOnly(requesting_origin) ||
       !cookie_settings->IsCookieAccessAllowed(requesting_origin,
                                               requesting_origin)) {
-    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
-                        false /* persist */, CONTENT_SETTING_DEFAULT);
+    NotifyPermissionSet(id, requesting_origin, embedding_origin,
+                        std::move(callback), false /* persist */,
+                        CONTENT_SETTING_DEFAULT);
     return;
   }
 
@@ -84,14 +86,16 @@
 
   for (const auto& important_site : important_sites) {
     if (important_site.registerable_domain == registerable_domain) {
-      NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
-                          true /* persist */, CONTENT_SETTING_ALLOW);
+      NotifyPermissionSet(id, requesting_origin, embedding_origin,
+                          std::move(callback), true /* persist */,
+                          CONTENT_SETTING_ALLOW);
       return;
     }
   }
 
-  NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
-                      false /* persist */, CONTENT_SETTING_DEFAULT);
+  NotifyPermissionSet(id, requesting_origin, embedding_origin,
+                      std::move(callback), false /* persist */,
+                      CONTENT_SETTING_DEFAULT);
 }
 
 void DurableStoragePermissionContext::UpdateContentSetting(
diff --git a/chrome/browser/storage/durable_storage_permission_context.h b/chrome/browser/storage/durable_storage_permission_context.h
index 67197017..3d84ca5 100644
--- a/chrome/browser/storage/durable_storage_permission_context.h
+++ b/chrome/browser/storage/durable_storage_permission_context.h
@@ -23,7 +23,7 @@
                         const GURL& requesting_origin,
                         const GURL& embedding_origin,
                         bool user_gesture,
-                        const BrowserPermissionCallback& callback) override;
+                        BrowserPermissionCallback callback) override;
   void UpdateContentSetting(const GURL& requesting_origin,
                             const GURL& embedding_origin,
                             ContentSetting content_setting) override;
diff --git a/chrome/browser/storage/durable_storage_permission_context_unittest.cc b/chrome/browser/storage/durable_storage_permission_context_unittest.cc
index 188b8fa..44784c8 100644
--- a/chrome/browser/storage/durable_storage_permission_context_unittest.cc
+++ b/chrome/browser/storage/durable_storage_permission_context_unittest.cc
@@ -59,14 +59,14 @@
   void NotifyPermissionSet(const PermissionRequestID& id,
                            const GURL& requesting_origin,
                            const GURL& embedder_origin,
-                           const BrowserPermissionCallback& callback,
+                           BrowserPermissionCallback callback,
                            bool persist,
                            ContentSetting content_setting) override {
     permission_set_count_++;
     last_permission_set_persisted_ = persist;
     last_permission_set_setting_ = content_setting;
     DurableStoragePermissionContext::NotifyPermissionSet(
-        id, requesting_origin, embedder_origin, callback, persist,
+        id, requesting_origin, embedder_origin, std::move(callback), persist,
         content_setting);
   }
 
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
index eca5944..74092965 100644
--- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc
+++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -8,21 +8,18 @@
 
 #include "base/callback.h"
 #include "base/command_line.h"
-#include "base/feature_list.h"
 #include "base/metrics/field_trial.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.h"
-#include "chrome/browser/supervised_user/experimental/safe_search_url_reporter.h"
 #include "chrome/browser/supervised_user/supervised_user_constants.h"
 #include "chrome/browser/supervised_user/supervised_user_service.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
@@ -193,10 +190,6 @@
         SupervisedUserServiceFactory::GetForProfile(profile_);
     service->AddPermissionRequestCreator(
         PermissionRequestCreatorApiary::CreateWithProfile(profile_));
-    if (base::FeatureList::IsEnabled(features::kSafeSearchUrlReporting)) {
-      service->SetSafeSearchURLReporter(
-          SafeSearchURLReporter::CreateWithProfile(profile_));
-    }
   } else {
     SupervisedUserSettingsService* settings_service =
         SupervisedUserSettingsServiceFactory::GetForKey(
diff --git a/chrome/browser/supervised_user/experimental/safe_search_url_reporter.cc b/chrome/browser/supervised_user/experimental/safe_search_url_reporter.cc
deleted file mode 100644
index bf4c9223..0000000
--- a/chrome/browser/supervised_user/experimental/safe_search_url_reporter.cc
+++ /dev/null
@@ -1,204 +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 "chrome/browser/supervised_user/experimental/safe_search_url_reporter.h"
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/stringprintf.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/supervised_user/supervised_user_constants.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/storage_partition.h"
-#include "google_apis/gaia/google_service_auth_error.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_status_code.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/identity/public/cpp/access_token_info.h"
-#include "services/identity/public/cpp/identity_manager.h"
-#include "services/identity/public/cpp/primary_account_access_token_fetcher.h"
-#include "services/network/public/cpp/resource_request.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/network/public/cpp/simple_url_loader.h"
-#include "url/gurl.h"
-
-const char kSafeSearchReportApiUrl[] =
-    "https://safesearch.googleapis.com/v1:report";
-const char kSafeSearchReportApiScope[] =
-    "https://www.googleapis.com/auth/safesearch.reporting";
-
-const int kNumSafeSearchReportRetries = 1;
-
-struct SafeSearchURLReporter::Report {
-  Report(const GURL& url, SuccessCallback callback);
-  ~Report();
-
-  GURL url;
-  SuccessCallback callback;
-  std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher>
-      access_token_fetcher;
-
-  std::string access_token;
-  bool access_token_expired;
-  std::unique_ptr<network::SimpleURLLoader> simple_url_loader;
-};
-
-SafeSearchURLReporter::Report::Report(const GURL& url, SuccessCallback callback)
-    : url(url), callback(std::move(callback)), access_token_expired(false) {}
-
-SafeSearchURLReporter::Report::~Report() {}
-
-SafeSearchURLReporter::SafeSearchURLReporter(
-    identity::IdentityManager* identity_manager,
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
-    : identity_manager_(identity_manager),
-      url_loader_factory_(std::move(url_loader_factory)) {}
-
-SafeSearchURLReporter::~SafeSearchURLReporter() {}
-
-// static
-std::unique_ptr<SafeSearchURLReporter> SafeSearchURLReporter::CreateWithProfile(
-    Profile* profile) {
-  auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
-  return std::make_unique<SafeSearchURLReporter>(
-      identity_manager,
-      content::BrowserContext::GetDefaultStoragePartition(profile)
-          ->GetURLLoaderFactoryForBrowserProcess());
-}
-
-void SafeSearchURLReporter::ReportUrl(const GURL& url,
-                                      SuccessCallback callback) {
-  reports_.push_back(std::make_unique<Report>(url, std::move(callback)));
-  StartFetching(reports_.back().get());
-}
-
-void SafeSearchURLReporter::StartFetching(Report* report) {
-  identity::ScopeSet scopes;
-  scopes.insert(kSafeSearchReportApiScope);
-  // It is safe to use Unretained(this) here given that the callback
-  // will not be invoke if this object is deleted. Likewise, |report|
-  // only comes from |reports_|, which are owned by this object too.
-  report->access_token_fetcher =
-      std::make_unique<identity::PrimaryAccountAccessTokenFetcher>(
-          "safe_search_url_reporter", identity_manager_, scopes,
-          base::BindOnce(&SafeSearchURLReporter::OnAccessTokenFetchComplete,
-                         base::Unretained(this), report),
-          identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate);
-}
-
-void SafeSearchURLReporter::OnAccessTokenFetchComplete(
-    Report* report,
-    GoogleServiceAuthError error,
-    identity::AccessTokenInfo token_info) {
-  auto it = reports_.begin();
-  while (it != reports_.end()) {
-    if (report->access_token_fetcher.get() ==
-        (*it)->access_token_fetcher.get()) {
-      break;
-    }
-    it++;
-  }
-  DCHECK(it != reports_.end());
-
-  if (error.state() != GoogleServiceAuthError::NONE) {
-    LOG(WARNING) << "Token error: " << error.ToString();
-    DispatchResult(it, false);
-    return;
-  }
-
-  (*it)->access_token = token_info.token;
-
-  net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation("safe_search_url_reporter", R"(
-        semantics {
-          sender: "Supervised Users"
-          description: "Reports a URL wrongfully flagged by SafeSearch."
-          trigger: "Initiated by the user."
-          data:
-            "The request is authenticated with an OAuth2 access token "
-            "identifying the Google account and contains the URL that was "
-            "wrongfully flagged."
-          destination: GOOGLE_OWNED_SERVICE
-        }
-        policy {
-          cookies_allowed: NO
-          setting:
-            "This feature cannot be disabled by settings and is only enabled "
-            "for child accounts. If sign-in is restricted to accounts from a "
-            "managed domain, those accounts are not going to be child accounts."
-          chrome_policy {
-            RestrictSigninToPattern {
-              policy_options {mode: MANDATORY}
-              RestrictSigninToPattern: "*@manageddomain.com"
-            }
-          }
-        })");
-  auto resource_request = std::make_unique<network::ResourceRequest>();
-  resource_request->url = GURL(kSafeSearchReportApiUrl);
-  resource_request->load_flags =
-      net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
-  resource_request->method = "POST";
-  resource_request->headers.SetHeader(
-      net::HttpRequestHeaders::kAuthorization,
-      base::StringPrintf(supervised_users::kAuthorizationHeaderFormat,
-                         token_info.token.c_str()));
-  (*it)->simple_url_loader = network::SimpleURLLoader::Create(
-      std::move(resource_request), traffic_annotation);
-
-  base::DictionaryValue dict;
-  dict.SetKey("url", base::Value((*it)->url.spec()));
-  std::string body;
-  base::JSONWriter::Write(dict, &body);
-  (*it)->simple_url_loader->AttachStringForUpload(body, "application/json");
-  (*it)->simple_url_loader->SetRetryOptions(
-      kNumSafeSearchReportRetries,
-      network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
-  // TODO(https://crbug.com/808498): Re-add data use measurement once
-  // SimpleURLLoader supports it.
-  // ID=data_use_measurement::DataUseUserData::SUPERVISED_USER
-  (*it)->simple_url_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
-      url_loader_factory_.get(),
-      base::BindOnce(&SafeSearchURLReporter::OnSimpleLoaderComplete,
-                     base::Unretained(this), std::move(it)));
-}
-
-void SafeSearchURLReporter::OnSimpleLoaderComplete(
-    ReportList::iterator it,
-    std::unique_ptr<std::string> response_body) {
-  Report* report = it->get();
-  std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
-      std::move(report->simple_url_loader);
-  int response_code = -1;
-  if (simple_url_loader->ResponseInfo() &&
-      simple_url_loader->ResponseInfo()->headers) {
-    response_code = simple_url_loader->ResponseInfo()->headers->response_code();
-  }
-  if (response_code == net::HTTP_UNAUTHORIZED &&
-      !report->access_token_expired) {
-    (*it)->access_token_expired = true;
-    identity::ScopeSet scopes;
-    scopes.insert(kSafeSearchReportApiScope);
-    identity_manager_->RemoveAccessTokenFromCache(
-        identity_manager_->GetPrimaryAccountId(), scopes, report->access_token);
-    StartFetching(report);
-    return;
-  }
-  if (response_code > 0) {
-    LOG(WARNING) << "HTTP error " << response_code;
-  } else if (!response_body) {
-    LOG(WARNING) << "Network error " << simple_url_loader->NetError();
-  }
-  DispatchResult(std::move(it), response_body != nullptr);
-}
-
-void SafeSearchURLReporter::DispatchResult(ReportList::iterator it,
-                                           bool success) {
-  std::move((*it)->callback).Run(success);
-  reports_.erase(it);
-}
diff --git a/chrome/browser/supervised_user/experimental/safe_search_url_reporter.h b/chrome/browser/supervised_user/experimental/safe_search_url_reporter.h
deleted file mode 100644
index 6f315f3..0000000
--- a/chrome/browser/supervised_user/experimental/safe_search_url_reporter.h
+++ /dev/null
@@ -1,68 +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 CHROME_BROWSER_SUPERVISED_USER_EXPERIMENTAL_SAFE_SEARCH_URL_REPORTER_H_
-#define CHROME_BROWSER_SUPERVISED_USER_EXPERIMENTAL_SAFE_SEARCH_URL_REPORTER_H_
-
-#include <list>
-#include <memory>
-
-#include "base/callback_forward.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "google_apis/gaia/google_service_auth_error.h"
-#include "url/gurl.h"
-
-class GURL;
-class Profile;
-
-namespace identity {
-class IdentityManager;
-struct AccessTokenInfo;
-}  // namespace identity
-
-namespace network {
-class SharedURLLoaderFactory;
-}
-
-class SafeSearchURLReporter {
- public:
-  using SuccessCallback = base::OnceCallback<void(bool)>;
-
-  SafeSearchURLReporter(
-      identity::IdentityManager* identity_manager,
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
-  ~SafeSearchURLReporter();
-
-  static std::unique_ptr<SafeSearchURLReporter> CreateWithProfile(
-      Profile* profile);
-
-  void ReportUrl(const GURL& url, SuccessCallback callback);
-
- private:
-  struct Report;
-  using ReportList = std::list<std::unique_ptr<Report>>;
-
-  void OnAccessTokenFetchComplete(Report* report,
-                                  GoogleServiceAuthError error,
-                                  identity::AccessTokenInfo token_info);
-
-  void OnSimpleLoaderComplete(ReportList::iterator it,
-                              std::unique_ptr<std::string> response_body);
-
-  // Requests an access token, which is the first thing we need. This is where
-  // we restart when the returned access token has expired.
-  void StartFetching(Report* Report);
-
-  void DispatchResult(ReportList::iterator it, bool success);
-
-  identity::IdentityManager* identity_manager_;
-  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
-
-  ReportList reports_;
-
-  DISALLOW_COPY_AND_ASSIGN(SafeSearchURLReporter);
-};
-
-#endif  // CHROME_BROWSER_SUPERVISED_USER_EXPERIMENTAL_SAFE_SEARCH_URL_REPORTER_H_
diff --git a/chrome/browser/supervised_user/experimental/safe_search_url_reporter_unittest.cc b/chrome/browser/supervised_user/experimental/safe_search_url_reporter_unittest.cc
deleted file mode 100644
index 5bbec988..0000000
--- a/chrome/browser/supervised_user/experimental/safe_search_url_reporter_unittest.cc
+++ /dev/null
@@ -1,110 +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 "chrome/browser/supervised_user/experimental/safe_search_url_reporter.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/values.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_util.h"
-#include "services/identity/public/cpp/identity_test_environment.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
-#include "services/network/test/test_url_loader_factory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const char kSafeSearchReportApiUrl[] =
-    "https://safesearch.googleapis.com/v1:report";
-const char kEmail[] = "account@gmail.com";
-
-}  // namespace
-
-class SafeSearchURLReporterTest : public testing::Test {
- public:
-  SafeSearchURLReporterTest()
-      : test_shared_loader_factory_(
-            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-                &test_url_loader_factory_)) {
-    AccountInfo account_info =
-        identity_test_env_.MakePrimaryAccountAvailable(kEmail);
-    account_id_ = account_info.account_id;
-    report_url_ = std::make_unique<SafeSearchURLReporter>(
-        identity_test_env_.identity_manager(), test_shared_loader_factory_);
-  }
-
- protected:
-  void IssueAccessTokens() {
-    identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
-        account_id_, "access_token",
-        base::Time::Now() + base::TimeDelta::FromHours(1));
-  }
-
-  void IssueAccessTokenErrors() {
-    identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
-        account_id_, GoogleServiceAuthError::FromServiceError("Error!"));
-  }
-
-  void SetupResponse(net::Error error) {
-    network::ResourceResponseHead head;
-    std::string headers("HTTP/1.1 200 OK\n\n");
-    head.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
-        net::HttpUtil::AssembleRawHeaders(headers));
-    network::URLLoaderCompletionStatus status(error);
-    test_url_loader_factory_.AddResponse(GURL(kSafeSearchReportApiUrl), head,
-                                         std::string(), status);
-  }
-
-  void CreateRequest(const GURL& url) {
-    report_url_->ReportUrl(
-        url, base::BindOnce(&SafeSearchURLReporterTest::OnRequestCreated,
-                            base::Unretained(this)));
-  }
-
-  void WaitForResponse() { base::RunLoop().RunUntilIdle(); }
-
-  MOCK_METHOD1(OnRequestCreated, void(bool success));
-
-  base::MessageLoop message_loop_;
-  std::string account_id_;
-  identity::IdentityTestEnvironment identity_test_env_;
-  network::TestURLLoaderFactory test_url_loader_factory_;
-  scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
-  std::unique_ptr<SafeSearchURLReporter> report_url_;
-};
-
-TEST_F(SafeSearchURLReporterTest, Success) {
-  CreateRequest(GURL("http://google.com"));
-  CreateRequest(GURL("http://url.com"));
-
-  IssueAccessTokens();
-
-  EXPECT_CALL(*this, OnRequestCreated(true)).Times(2);
-  SetupResponse(net::OK);
-  SetupResponse(net::OK);
-  WaitForResponse();
-}
-
-TEST_F(SafeSearchURLReporterTest, AccessTokenError) {
-  CreateRequest(GURL("http://google.com"));
-
-  EXPECT_CALL(*this, OnRequestCreated(false));
-  IssueAccessTokenErrors();
-}
-
-TEST_F(SafeSearchURLReporterTest, NetworkError) {
-  CreateRequest(GURL("http://google.com"));
-
-  IssueAccessTokens();
-
-  EXPECT_CALL(*this, OnRequestCreated(false));
-  SetupResponse(net::ERR_ABORTED);
-  WaitForResponse();
-}
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index ea6b96b..8d9e817 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -207,14 +207,6 @@
       std::move(callback), 0);
 }
 
-void SupervisedUserService::ReportURL(const GURL& url,
-                                      SuccessCallback callback) {
-  if (url_reporter_)
-    url_reporter_->ReportUrl(url, std::move(callback));
-  else
-    std::move(callback).Run(false);
-}
-
 void SupervisedUserService::AddExtensionInstallRequest(
     const std::string& extension_id,
     const base::Version& version,
@@ -333,11 +325,6 @@
   permissions_creators_.push_back(std::move(creator));
 }
 
-void SupervisedUserService::SetSafeSearchURLReporter(
-    std::unique_ptr<SafeSearchURLReporter> reporter) {
-  url_reporter_ = std::move(reporter);
-}
-
 SupervisedUserService::SupervisedUserService(Profile* profile)
     : profile_(profile),
       active_(false),
@@ -443,7 +430,6 @@
 #endif
   } else {
     permissions_creators_.clear();
-    url_reporter_.reset();
 
     pref_change_registrar_.Remove(
         prefs::kDefaultSupervisedUserFilteringBehavior);
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h
index d9b83f2a..bdc6e46 100644
--- a/chrome/browser/supervised_user/supervised_user_service.h
+++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -20,7 +20,6 @@
 #include "base/strings/string16.h"
 #include "build/build_config.h"
 #include "chrome/browser/net/file_downloader.h"
-#include "chrome/browser/supervised_user/experimental/safe_search_url_reporter.h"
 #include "chrome/browser/supervised_user/experimental/supervised_user_blacklist.h"
 #include "chrome/browser/supervised_user/supervised_user_url_filter.h"
 #include "chrome/browser/supervised_user/supervised_users.h"
@@ -109,10 +108,6 @@
   // Adds an access request for the given URL.
   void AddURLAccessRequest(const GURL& url, SuccessCallback callback);
 
-  // Reports |url| to the SafeSearch API, because the user thinks this is an
-  // inappropriate URL.
-  void ReportURL(const GURL& url, SuccessCallback callback);
-
   // Adds an install request for the given WebStore item (App/Extension).
   void AddExtensionInstallRequest(const std::string& extension_id,
                                   const base::Version& version,
@@ -167,9 +162,6 @@
   void AddPermissionRequestCreator(
       std::unique_ptr<PermissionRequestCreator> creator);
 
-  void SetSafeSearchURLReporter(
-      std::unique_ptr<SafeSearchURLReporter> reporter);
-
   // ProfileKeyedService override:
   void Shutdown() override;
 
@@ -344,9 +336,6 @@
   // Used to create permission requests.
   std::vector<std::unique_ptr<PermissionRequestCreator>> permissions_creators_;
 
-  // Used to report inappropriate URLs to SafeSarch API.
-  std::unique_ptr<SafeSearchURLReporter> url_reporter_;
-
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   ScopedObserver<extensions::ExtensionRegistry,
                  extensions::ExtensionRegistryObserver>
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 c46c3b7..2341343 100644
--- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
+++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
@@ -145,6 +145,13 @@
         base::BindRepeating(
             &CredentialProviderWebUIMessageHandler::OnSigninComplete,
             base::Unretained(this)));
+
+    // This message is always sent as part of the SAML flow but we don't really
+    // need to process it. We do however have to handle the message or else
+    // there will be a DCHECK failure in web_ui about an unhandled message.
+    web_ui()->RegisterMessageCallback(
+        "updatePasswordAttributes",
+        base::BindRepeating([](const base::ListValue* args) {}));
   }
 
   void AbortIfPossible() {
diff --git a/chrome/browser/ui/views/frame/browser_frame_ash.cc b/chrome/browser/ui/views/frame/browser_frame_ash.cc
index 13b8994a..b3f4a38 100644
--- a/chrome/browser/ui/views/frame/browser_frame_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_frame_ash.cc
@@ -90,6 +90,15 @@
   window_state->SetCanConsumeSystemKeys(browser->is_app());
 }
 
+void BrowserFrameAsh::OnBoundsChanged(const gfx::Rect& old_bounds,
+                                      const gfx::Rect& new_bounds) {
+  NativeWidgetAura::OnBoundsChanged(old_bounds, new_bounds);
+  if (GetNativeWindow()->transparent()) {
+    GetNativeWindow()->SetOpaqueRegionsForOcclusion(
+        {gfx::Rect(new_bounds.size())});
+  }
+}
+
 void BrowserFrameAsh::OnWindowTargetVisibilityChanged(bool visible) {
   if (visible) {
     // Once the window has been shown we know the requested bounds
diff --git a/chrome/browser/ui/views/frame/browser_frame_ash.h b/chrome/browser/ui/views/frame/browser_frame_ash.h
index 77928a5..e7856990 100644
--- a/chrome/browser/ui/views/frame/browser_frame_ash.h
+++ b/chrome/browser/ui/views/frame/browser_frame_ash.h
@@ -24,6 +24,8 @@
 
   // Overridden from views::NativeWidgetAura:
   void OnWidgetInitDone() override;
+  void OnBoundsChanged(const gfx::Rect& old_bounds,
+                       const gfx::Rect& new_bounds) override;
   void OnWindowTargetVisibilityChanged(bool visible) override;
 
   // Overridden from NativeBrowserFrame:
diff --git a/chrome/browser/ui/views/overlay/back_to_tab_image_button.cc b/chrome/browser/ui/views/overlay/back_to_tab_image_button.cc
index fae1519e..a8113a2 100644
--- a/chrome/browser/ui/views/overlay/back_to_tab_image_button.cc
+++ b/chrome/browser/ui/views/overlay/back_to_tab_image_button.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/views/overlay/back_to_tab_image_button.h"
 
-#include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/grit/generated_resources.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -14,10 +13,8 @@
 
 namespace {
 
-const int kBackToTabButtonMargin = 8;
-const int kBackToTabButtonSize = 24;
+const int kBackToTabImageSize = 12;
 
-constexpr SkColor kBackToTabBgColor = gfx::kGoogleGrey700;
 constexpr SkColor kBackToTabIconColor = SK_ColorWHITE;
 
 }  // namespace
@@ -25,19 +22,11 @@
 namespace views {
 
 BackToTabImageButton::BackToTabImageButton(ButtonListener* listener)
-    : ImageButton(listener),
-      back_to_tab_background_(
-          gfx::CreateVectorIcon(kPictureInPictureControlBackgroundIcon,
-                                kBackToTabButtonSize,
-                                kBackToTabBgColor)) {
+    : ImageButton(listener) {
   SetImageAlignment(views::ImageButton::ALIGN_CENTER,
                     views::ImageButton::ALIGN_MIDDLE);
-  SetBackgroundImageAlignment(views::ImageButton::ALIGN_LEFT,
-                              views::ImageButton::ALIGN_TOP);
-  SetSize(gfx::Size(kBackToTabButtonSize, kBackToTabButtonSize));
   SetImage(views::Button::STATE_NORMAL,
-           gfx::CreateVectorIcon(views::kLaunchIcon,
-                                 std::round(kBackToTabButtonSize * 2.0 / 3.0),
+           gfx::CreateVectorIcon(views::kLaunchIcon, kBackToTabImageSize,
                                  kBackToTabIconColor));
 
   // Accessibility.
@@ -49,42 +38,4 @@
   SetInstallFocusRingOnFocus(true);
 }
 
-void BackToTabImageButton::StateChanged(ButtonState old_state) {
-  ImageButton::StateChanged(old_state);
-
-  if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
-    SetBackgroundImage(kBackToTabBgColor, &back_to_tab_background_,
-                       &back_to_tab_background_);
-  } else {
-    SetBackgroundImage(kBackToTabBgColor, nullptr, nullptr);
-  }
-}
-
-void BackToTabImageButton::OnFocus() {
-  ImageButton::OnFocus();
-  SetBackgroundImage(kBackToTabBgColor, &back_to_tab_background_,
-                     &back_to_tab_background_);
-}
-
-void BackToTabImageButton::OnBlur() {
-  ImageButton::OnBlur();
-  SetBackgroundImage(kBackToTabBgColor, nullptr, nullptr);
-}
-
-void BackToTabImageButton::SetPosition(
-    const gfx::Size& size,
-    OverlayWindowViews::WindowQuadrant quadrant) {
-#if defined(OS_CHROMEOS)
-  if (quadrant == OverlayWindowViews::WindowQuadrant::kTopLeft) {
-    ImageButton::SetPosition(gfx::Point(
-        kBackToTabButtonMargin,
-        size.height() - kBackToTabButtonSize - kBackToTabButtonMargin));
-    return;
-  }
-#endif
-  ImageButton::SetPosition(gfx::Point(
-      size.width() - kBackToTabButtonSize - kBackToTabButtonMargin,
-      size.height() - kBackToTabButtonSize - kBackToTabButtonMargin));
-}
-
 }  // namespace views
diff --git a/chrome/browser/ui/views/overlay/back_to_tab_image_button.h b/chrome/browser/ui/views/overlay/back_to_tab_image_button.h
index 813527a..aacaeb3 100644
--- a/chrome/browser/ui/views/overlay/back_to_tab_image_button.h
+++ b/chrome/browser/ui/views/overlay/back_to_tab_image_button.h
@@ -10,27 +10,13 @@
 
 namespace views {
 
-// An image button representing a back-to-tab button. When user hovers/focuses
-// the button, a grey circular background appears as an indicator.
+// An image button representing a back-to-tab button.
 class BackToTabImageButton : public views::ImageButton {
  public:
   explicit BackToTabImageButton(ButtonListener*);
   ~BackToTabImageButton() override = default;
 
-  // views::Button:
-  void StateChanged(ButtonState old_state) override;
-
-  // views::View:
-  void OnFocus() override;
-  void OnBlur() override;
-
-  // Sets the position of itself with an offset from the given window size.
-  void SetPosition(const gfx::Size& size,
-                   OverlayWindowViews::WindowQuadrant quadrant);
-
  private:
-  const gfx::ImageSkia back_to_tab_background_;
-
   DISALLOW_COPY_AND_ASSIGN(BackToTabImageButton);
 };
 
diff --git a/chrome/browser/ui/views/overlay/close_image_button.cc b/chrome/browser/ui/views/overlay/close_image_button.cc
index 65e0eb97..b68170b 100644
--- a/chrome/browser/ui/views/overlay/close_image_button.cc
+++ b/chrome/browser/ui/views/overlay/close_image_button.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/views/overlay/close_image_button.h"
 
-#include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/grit/generated_resources.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -15,9 +14,8 @@
 namespace {
 
 const int kCloseButtonMargin = 8;
-const int kCloseButtonSize = 24;
+const int kCloseButtonSize = 16;
 
-constexpr SkColor kCloseBgColor = gfx::kGoogleGrey700;
 constexpr SkColor kCloseIconColor = SK_ColorWHITE;
 
 }  // namespace
@@ -25,19 +23,12 @@
 namespace views {
 
 CloseImageButton::CloseImageButton(ButtonListener* listener)
-    : ImageButton(listener),
-      close_background_(
-          gfx::CreateVectorIcon(kPictureInPictureControlBackgroundIcon,
-                                kCloseButtonSize,
-                                kCloseBgColor)) {
+    : ImageButton(listener) {
   SetImageAlignment(views::ImageButton::ALIGN_CENTER,
                     views::ImageButton::ALIGN_MIDDLE);
-  SetBackgroundImageAlignment(views::ImageButton::ALIGN_LEFT,
-                              views::ImageButton::ALIGN_TOP);
   SetSize(gfx::Size(kCloseButtonSize, kCloseButtonSize));
   SetImage(views::Button::STATE_NORMAL,
-           gfx::CreateVectorIcon(views::kIcCloseIcon,
-                                 std::round(kCloseButtonSize * 2.0 / 3.0),
+           gfx::CreateVectorIcon(views::kIcCloseIcon, kCloseButtonSize,
                                  kCloseIconColor));
 
   // Accessibility.
@@ -49,25 +40,6 @@
   SetInstallFocusRingOnFocus(true);
 }
 
-void CloseImageButton::StateChanged(ButtonState old_state) {
-  ImageButton::StateChanged(old_state);
-
-  if (state() == STATE_HOVERED || state() == STATE_PRESSED)
-    SetBackgroundImage(kCloseBgColor, &close_background_, &close_background_);
-  else
-    SetBackgroundImage(kCloseBgColor, nullptr, nullptr);
-}
-
-void CloseImageButton::OnFocus() {
-  ImageButton::OnFocus();
-  SetBackgroundImage(kCloseBgColor, &close_background_, &close_background_);
-}
-
-void CloseImageButton::OnBlur() {
-  ImageButton::OnBlur();
-  SetBackgroundImage(kCloseBgColor, nullptr, nullptr);
-}
-
 void CloseImageButton::SetPosition(
     const gfx::Size& size,
     OverlayWindowViews::WindowQuadrant quadrant) {
diff --git a/chrome/browser/ui/views/overlay/close_image_button.h b/chrome/browser/ui/views/overlay/close_image_button.h
index 7b58e6a..887f272b 100644
--- a/chrome/browser/ui/views/overlay/close_image_button.h
+++ b/chrome/browser/ui/views/overlay/close_image_button.h
@@ -10,27 +10,17 @@
 
 namespace views {
 
-// An image button representing a white close button. When the user interacts
-// with the button, a grey circular background appears as an indicator.
+// An image button representing a close button.
 class CloseImageButton : public views::ImageButton {
  public:
   explicit CloseImageButton(ButtonListener*);
   ~CloseImageButton() override = default;
 
-  // views::Button:
-  void StateChanged(ButtonState old_state) override;
-
-  // views::View:
-  void OnFocus() override;
-  void OnBlur() override;
-
   // Sets the position of itself with an offset from the given window size.
   void SetPosition(const gfx::Size& size,
                    OverlayWindowViews::WindowQuadrant quadrant);
 
  private:
-  const gfx::ImageSkia close_background_;
-
   DISALLOW_COPY_AND_ASSIGN(CloseImageButton);
 };
 
diff --git a/chrome/browser/ui/views/overlay/mute_image_button.cc b/chrome/browser/ui/views/overlay/mute_image_button.cc
index d60a646..1743c32 100644
--- a/chrome/browser/ui/views/overlay/mute_image_button.cc
+++ b/chrome/browser/ui/views/overlay/mute_image_button.cc
@@ -15,10 +15,8 @@
 
 namespace {
 
-const int kMuteButtonMargin = 8;
-const int kMuteButtonSize = 24;
+const int kMuteImageSize = 18;
 
-constexpr SkColor kMuteBgColor = gfx::kGoogleGrey700;
 constexpr SkColor kMuteIconColor = SK_ColorWHITE;
 
 }  // namespace
@@ -27,20 +25,13 @@
 
 MuteImageButton::MuteImageButton(ButtonListener* listener)
     : ImageButton(listener),
-      mute_background_(
-          gfx::CreateVectorIcon(kPictureInPictureControlBackgroundIcon,
-                                kMuteButtonSize,
-                                kMuteBgColor)),
-      mute_image_(gfx::CreateVectorIcon(kTabAudioIcon,
-                                        std::round(kMuteButtonSize * 2.0 / 3.0),
-                                        kMuteIconColor)),
-      unmute_image_(
-          gfx::CreateVectorIcon(kTabAudioMutingIcon,
-                                std::round(kMuteButtonSize * 2.0 / 3.0),
-                                kMuteIconColor)) {
+      mute_image_(
+          gfx::CreateVectorIcon(kTabAudioIcon, kMuteImageSize, kMuteIconColor)),
+      unmute_image_(gfx::CreateVectorIcon(kTabAudioMutingIcon,
+                                          kMuteImageSize,
+                                          kMuteIconColor)) {
   SetImageAlignment(views::ImageButton::ALIGN_CENTER,
                     views::ImageButton::ALIGN_MIDDLE);
-  SetSize(gfx::Size(kMuteButtonSize, kMuteButtonSize));
 
   // Accessibility.
   SetFocusForPlatform();
@@ -50,38 +41,6 @@
   SetInstallFocusRingOnFocus(true);
 }
 
-void MuteImageButton::StateChanged(ButtonState old_state) {
-  ImageButton::StateChanged(old_state);
-
-  if (state() == STATE_HOVERED || state() == STATE_PRESSED)
-    SetBackgroundImage(kMuteBgColor, &mute_background_, &mute_background_);
-  else
-    SetBackgroundImage(kMuteBgColor, nullptr, nullptr);
-}
-
-void MuteImageButton::OnFocus() {
-  ImageButton::OnFocus();
-  SetBackgroundImage(kMuteBgColor, &mute_background_, &mute_background_);
-}
-
-void MuteImageButton::OnBlur() {
-  ImageButton::OnBlur();
-  SetBackgroundImage(kMuteBgColor, nullptr, nullptr);
-}
-
-void MuteImageButton::SetPosition(const gfx::Size& size,
-                                  OverlayWindowViews::WindowQuadrant quadrant) {
-#if defined(OS_CHROMEOS)
-  if (quadrant == OverlayWindowViews::WindowQuadrant::kTopLeft ||
-      quadrant == OverlayWindowViews::WindowQuadrant::kTopRight) {
-    ImageButton::SetPosition(gfx::Point(kMuteButtonMargin, kMuteButtonMargin));
-    return;
-  }
-#endif
-  ImageButton::SetPosition(gfx::Point(
-      kMuteButtonMargin, size.height() - kMuteButtonSize - kMuteButtonMargin));
-}
-
 void MuteImageButton::SetMutedState(
     OverlayWindowViews::MutedState muted_state) {
   muted_state_ = muted_state;
@@ -99,6 +58,16 @@
     case OverlayWindowViews::kNoAudio:
       ToggleVisibility(false);
   }
+  SchedulePaint();
+}
+
+gfx::Size MuteImageButton::GetLastVisibleSize() const {
+  return size().IsEmpty() ? last_visible_size_ : size();
+}
+
+void MuteImageButton::OnBoundsChanged(const gfx::Rect&) {
+  if (!size().IsEmpty())
+    last_visible_size_ = size();
 }
 
 void MuteImageButton::ToggleVisibility(bool is_visible) {
@@ -107,8 +76,7 @@
 
   layer()->SetVisible(is_visible);
   SetEnabled(is_visible);
-  SetSize(is_visible ? gfx::Size(kMuteButtonSize, kMuteButtonSize)
-                     : gfx::Size());
+  SetSize(is_visible ? GetLastVisibleSize() : gfx::Size());
 }
 
 }  // namespace views
diff --git a/chrome/browser/ui/views/overlay/mute_image_button.h b/chrome/browser/ui/views/overlay/mute_image_button.h
index f8ccf41..c1bbcdc 100644
--- a/chrome/browser/ui/views/overlay/mute_image_button.h
+++ b/chrome/browser/ui/views/overlay/mute_image_button.h
@@ -10,36 +10,34 @@
 
 namespace views {
 
-// An image button representing a white mute button. When the user interacts
-// with the button, a grey circular background appears as an indicator.
+// An image button representing a mute button.
 class MuteImageButton : public views::ImageButton {
  public:
   explicit MuteImageButton(ButtonListener*);
   ~MuteImageButton() override = default;
 
-  // views::Button:
-  void StateChanged(ButtonState old_state) override;
-
-  // views::View:
-  void OnFocus() override;
-  void OnBlur() override;
-
-  // Sets the position of itself with an offset from the given window size.
-  void SetPosition(const gfx::Size&, OverlayWindowViews::WindowQuadrant);
-
   // Show mute/unmute image and update tooltip based on video muted status.
   void SetMutedState(OverlayWindowViews::MutedState);
 
+  // Get button size when visible.
+  gfx::Size GetLastVisibleSize() const;
+
   // Toggle visibility.
   void ToggleVisibility(bool is_visible);
 
+ protected:
+  // Overridden from views::View.
+  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
+
  private:
-  const gfx::ImageSkia mute_background_;
   const gfx::ImageSkia mute_image_;
   const gfx::ImageSkia unmute_image_;
 
   OverlayWindowViews::MutedState muted_state_;
 
+  // Last visible size of the image button.
+  gfx::Size last_visible_size_;
+
   DISALLOW_COPY_AND_ASSIGN(MuteImageButton);
 };
 
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index 39e0fca8..02709569 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -52,20 +52,32 @@
 }
 
 namespace {
-constexpr gfx::Size kMinWindowSize = gfx::Size(144, 100);
+constexpr gfx::Size kMinWindowSize = gfx::Size(260, 146);
 
 const int kOverlayBorderThickness = 10;
 
-// play/pause control scales both its width and height to be 30% the size of
-// the smaller of the screen's width and height.
-const float kPlayPauseControlRatioToWindow = 0.3;
+// The opacity of the controls scrim.
+const double kControlsScrimOpacity = 0.6;
 
-// track controls scales both their width and height to be 60% the size of the
-// play/pause control.
-const float kTrackControlRatioToPlayPauseControl = 0.6;
+#if defined(OS_CHROMEOS)
+// The opacity of the resize handle control.
+const double kResizeHandleOpacity = 0.38;
+#endif
 
-const int kMinControlButtonSize = 48;
-const int kControlButtonMargin = 12;
+// Size of a primary control.
+constexpr gfx::Size kPrimaryControlSize = gfx::Size(36, 36);
+
+// Margin from the bottom of the window for primary controls.
+const int kPrimaryControlBottomMargin = 8;
+
+// Size of a secondary control.
+constexpr gfx::Size kSecondaryControlSize = gfx::Size(20, 20);
+
+// Margin from the bottom of the window for secondary controls.
+const int kSecondaryControlBottomMargin = 16;
+
+// Margin between controls.
+const int kControlMargin = 32;
 
 // Returns the quadrant the OverlayWindowViews is primarily in on the current
 // work area.
@@ -190,25 +202,24 @@
       window_background_view_(new views::View()),
       video_view_(new views::View()),
       controls_scrim_view_(new views::View()),
-      controls_parent_view_(new views::View()),
-      back_to_tab_controls_view_(new views::BackToTabImageButton(this)),
-      mute_controls_view_(new views::MuteImageButton(this)),
-      skip_ad_controls_view_(new views::SkipAdLabelButton(this)),
       close_controls_view_(new views::CloseImageButton(this)),
-#if defined(OS_CHROMEOS)
-      resize_handle_view_(new views::ResizeHandleButton(this)),
-#endif
+      back_to_tab_controls_view_(new views::BackToTabImageButton(this)),
+      previous_track_controls_view_(new views::TrackImageButton(
+          this,
+          vector_icons::kMediaPreviousTrackIcon,
+          l10n_util::GetStringUTF16(
+              IDS_PICTURE_IN_PICTURE_PREVIOUS_TRACK_CONTROL_ACCESSIBLE_TEXT))),
       play_pause_controls_view_(new views::PlaybackImageButton(this)),
       next_track_controls_view_(new views::TrackImageButton(
           this,
           vector_icons::kMediaNextTrackIcon,
           l10n_util::GetStringUTF16(
               IDS_PICTURE_IN_PICTURE_NEXT_TRACK_CONTROL_ACCESSIBLE_TEXT))),
-      previous_track_controls_view_(new views::TrackImageButton(
-          this,
-          vector_icons::kMediaPreviousTrackIcon,
-          l10n_util::GetStringUTF16(
-              IDS_PICTURE_IN_PICTURE_PREVIOUS_TRACK_CONTROL_ACCESSIBLE_TEXT))),
+      mute_controls_view_(new views::MuteImageButton(this)),
+      skip_ad_controls_view_(new views::SkipAdLabelButton(this)),
+#if defined(OS_CHROMEOS)
+      resize_handle_view_(new views::ResizeHandleButton(this)),
+#endif
       hide_controls_timer_(
           FROM_HERE,
           base::TimeDelta::FromMilliseconds(2500 /* 2.5 seconds */),
@@ -350,19 +361,25 @@
   window_background_view_->layer()->set_name("WindowBackgroundView");
   window_background_view_->layer()->SetColor(SK_ColorBLACK);
 
+  // view::View that holds the video. -----------------------------------------
+  video_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
+  video_view_->SetSize(GetBounds().size());
+  video_view_->layer()->SetMasksToBounds(true);
+  video_view_->layer()->SetFillsBoundsOpaquely(false);
+  video_view_->layer()->set_name("VideoView");
+
   // views::View that holds the scrim, which appears with the controls. -------
   controls_scrim_view_->SetSize(GetBounds().size());
   controls_scrim_view_->SetPaintToLayer(ui::LAYER_SOLID_COLOR);
   controls_scrim_view_->layer()->set_name("ControlsScrimView");
   GetControlsScrimLayer()->SetColor(gfx::kGoogleGrey900);
-  GetControlsScrimLayer()->SetOpacity(0.43f);
+  GetControlsScrimLayer()->SetOpacity(kControlsScrimOpacity);
 
-  // view::View that holds the controls. --------------------------------------
-  controls_parent_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
-  controls_parent_view_->SetSize(GetBounds().size());
-  controls_parent_view_->layer()->SetFillsBoundsOpaquely(false);
-  controls_parent_view_->layer()->set_name("ControlsParentView");
-  controls_parent_view_->set_owned_by_client();
+  // views::View that closes the window. --------------------------------------
+  close_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
+  close_controls_view_->layer()->SetFillsBoundsOpaquely(false);
+  close_controls_view_->layer()->set_name("CloseControlsView");
+  close_controls_view_->set_owned_by_client();
 
   // views::View that closes the window and focuses initiator tab. ------------
   back_to_tab_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
@@ -370,6 +387,26 @@
   back_to_tab_controls_view_->layer()->set_name("BackToTabControlsView");
   back_to_tab_controls_view_->set_owned_by_client();
 
+  // views::View that holds the previous-track image button. ------------------
+  previous_track_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
+  previous_track_controls_view_->layer()->SetFillsBoundsOpaquely(false);
+  previous_track_controls_view_->layer()->set_name("PreviousTrackControlsView");
+  previous_track_controls_view_->set_owned_by_client();
+
+  // views::View that toggles play/pause/replay. ------------------------------
+  play_pause_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
+  play_pause_controls_view_->layer()->SetFillsBoundsOpaquely(false);
+  play_pause_controls_view_->layer()->set_name("PlayPauseControlsView");
+  play_pause_controls_view_->SetPlaybackState(
+      controller_->IsPlayerActive() ? kPlaying : kPaused);
+  play_pause_controls_view_->set_owned_by_client();
+
+  // views::View that holds the next-track image button. ----------------------
+  next_track_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
+  next_track_controls_view_->layer()->SetFillsBoundsOpaquely(false);
+  next_track_controls_view_->layer()->set_name("NextTrackControlsView");
+  next_track_controls_view_->set_owned_by_client();
+
   // views::View that holds the mute image button. -------------------------
   mute_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
   mute_controls_view_->layer()->SetFillsBoundsOpaquely(false);
@@ -383,55 +420,30 @@
   skip_ad_controls_view_->layer()->set_name("SkipAdControlsView");
   skip_ad_controls_view_->set_owned_by_client();
 
-  // views::View that closes the window. --------------------------------------
-  close_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
-  close_controls_view_->layer()->SetFillsBoundsOpaquely(false);
-  close_controls_view_->layer()->set_name("CloseControlsView");
-  close_controls_view_->set_owned_by_client();
-
-  // view::View that holds the video. -----------------------------------------
-  video_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
-  video_view_->SetSize(GetBounds().size());
-  video_view_->layer()->SetMasksToBounds(true);
-  video_view_->layer()->SetFillsBoundsOpaquely(false);
-  video_view_->layer()->set_name("VideoView");
-
-  // views::View that toggles play/pause/replay. ------------------------------
-  play_pause_controls_view_->SetPlaybackState(
-      controller_->IsPlayerActive() ? kPlaying : kPaused);
-  play_pause_controls_view_->set_owned_by_client();
-
-  // views::View that holds the next-track image button. ----------------------
-  next_track_controls_view_->set_owned_by_client();
-
-  // views::View that holds the previous-track image button. ------------------
-  previous_track_controls_view_->set_owned_by_client();
-
 #if defined(OS_CHROMEOS)
   // views::View that shows the affordance that the window can be resized. ----
   resize_handle_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
   resize_handle_view_->layer()->SetFillsBoundsOpaquely(false);
   resize_handle_view_->layer()->set_name("ResizeHandleView");
+  resize_handle_view_->layer()->SetOpacity(kResizeHandleOpacity);
   resize_handle_view_->set_owned_by_client();
 #endif
 
   // Set up view::Views hierarchy. --------------------------------------------
-  controls_parent_view_->AddChildView(play_pause_controls_view_.get());
-  controls_parent_view_->AddChildView(next_track_controls_view_.get());
-  controls_parent_view_->AddChildView(previous_track_controls_view_.get());
   GetContentsView()->AddChildView(window_background_view_.get());
   GetContentsView()->AddChildView(video_view_.get());
   GetContentsView()->AddChildView(controls_scrim_view_.get());
-  GetContentsView()->AddChildView(controls_parent_view_.get());
-  GetContentsView()->AddChildView(skip_ad_controls_view_.get());
-  GetContentsView()->AddChildView(back_to_tab_controls_view_.get());
-  GetContentsView()->AddChildView(mute_controls_view_.get());
   GetContentsView()->AddChildView(close_controls_view_.get());
+  GetContentsView()->AddChildView(back_to_tab_controls_view_.get());
+  GetContentsView()->AddChildView(previous_track_controls_view_.get());
+  GetContentsView()->AddChildView(play_pause_controls_view_.get());
+  GetContentsView()->AddChildView(next_track_controls_view_.get());
+  GetContentsView()->AddChildView(mute_controls_view_.get());
+  GetContentsView()->AddChildView(skip_ad_controls_view_.get());
 #if defined(OS_CHROMEOS)
   GetContentsView()->AddChildView(resize_handle_view_.get());
 #endif
 
-  UpdateButtonControlsSize();
   UpdateControlsVisibility(false);
 }
 
@@ -478,16 +490,15 @@
 }
 
 void OverlayWindowViews::UpdateControlsVisibility(bool is_visible) {
+  GetControlsScrimLayer()->SetVisible(is_visible);
+  GetCloseControlsLayer()->SetVisible(is_visible);
+  GetBackToTabControlsLayer()->SetVisible(is_visible);
+  previous_track_controls_view_->ToggleVisibility(is_visible &&
+                                                  show_previous_track_button_);
   play_pause_controls_view_->SetVisible(is_visible &&
                                         !always_hide_play_pause_button_);
   next_track_controls_view_->ToggleVisibility(is_visible &&
                                               show_next_track_button_);
-  previous_track_controls_view_->ToggleVisibility(is_visible &&
-                                                  show_previous_track_button_);
-  GetControlsScrimLayer()->SetVisible(is_visible);
-  GetControlsParentLayer()->SetVisible(is_visible);
-  GetBackToTabControlsLayer()->SetVisible(is_visible);
-  GetCloseControlsLayer()->SetVisible(is_visible);
 
   // We need to do more than usual visibility change because otherwise control
   // is accessible via accessibility tools.
@@ -508,35 +519,145 @@
   controls_scrim_view_->SetBoundsRect(larger_window_bounds);
 
   WindowQuadrant quadrant = GetCurrentWindowQuadrant(GetBounds(), controller_);
-  back_to_tab_controls_view_->SetPosition(GetBounds().size(), quadrant);
-  mute_controls_view_->SetPosition(GetBounds().size(), quadrant);
-  skip_ad_controls_view_->SetPosition(GetBounds().size());
   close_controls_view_->SetPosition(GetBounds().size(), quadrant);
 #if defined(OS_CHROMEOS)
   resize_handle_view_->SetPosition(GetBounds().size(), quadrant);
 #endif
 
-  controls_parent_view_->SetBoundsRect(
-      gfx::Rect(gfx::Point(0, 0), GetBounds().size()));
+  skip_ad_controls_view_->SetPosition(GetBounds().size());
+
+  // Following controls order matters:
+  // #1 Back to tab
+  // #2 Previous track
+  // #3 Play/Pause
+  // #4 Next track
+  // #5 Mute
+  std::vector<views::ImageButton*> visible_controls_views;
+  visible_controls_views.push_back(back_to_tab_controls_view_.get());
+  if (show_previous_track_button_)
+    visible_controls_views.push_back(previous_track_controls_view_.get());
+  if (!always_hide_play_pause_button_)
+    visible_controls_views.push_back(play_pause_controls_view_.get());
+  if (show_next_track_button_)
+    visible_controls_views.push_back(next_track_controls_view_.get());
+  if (show_mute_button_)
+    visible_controls_views.push_back(mute_controls_view_.get());
 
   int mid_window_x = GetBounds().size().width() / 2;
-  play_pause_controls_view_->SetBoundsRect(CalculateControlsBounds(
-      mid_window_x - play_pause_controls_view_->size().width() / 2,
-      play_pause_controls_view_->size()));
+  int primary_control_y = GetBounds().size().height() -
+                          kPrimaryControlSize.height() -
+                          kPrimaryControlBottomMargin;
+  int secondary_control_y = GetBounds().size().height() -
+                            kSecondaryControlSize.height() -
+                            kSecondaryControlBottomMargin;
 
-  if (show_next_track_button_) {
-    next_track_controls_view_->SetBoundsRect(CalculateControlsBounds(
-        mid_window_x + play_pause_controls_view_->size().width() / 2 +
-            kControlButtonMargin,
-        next_track_controls_view_->GetLastVisibleSize()));
+  switch (visible_controls_views.size()) {
+    case 1: {
+      /* | --- --- [ ] --- --- | */
+      visible_controls_views[0]->SetSize(kSecondaryControlSize);
+      visible_controls_views[0]->SetPosition(
+          gfx::Point(mid_window_x - kSecondaryControlSize.width() / 2,
+                     secondary_control_y));
+      return;
+    }
+    case 2: {
+      /* | ----- [ ] [ ] ----- | */
+      visible_controls_views[0]->SetSize(kSecondaryControlSize);
+      visible_controls_views[0]->SetPosition(gfx::Point(
+          mid_window_x - kControlMargin / 2 - kSecondaryControlSize.width(),
+          secondary_control_y));
+
+      visible_controls_views[1]->SetSize(kSecondaryControlSize);
+      visible_controls_views[1]->SetPosition(
+          gfx::Point(mid_window_x + kControlMargin / 2, secondary_control_y));
+      return;
+    }
+    case 3: {
+      /* | --- [ ] [ ] [ ] --- | */
+      visible_controls_views[0]->SetSize(kSecondaryControlSize);
+      visible_controls_views[0]->SetPosition(
+          gfx::Point(mid_window_x - kPrimaryControlSize.width() / 2 -
+                         kControlMargin - kSecondaryControlSize.width(),
+                     secondary_control_y));
+
+      // Middle control is primary only if it's play/pause control.
+      if (visible_controls_views[1] == play_pause_controls_view_.get()) {
+        visible_controls_views[1]->SetSize(kPrimaryControlSize);
+        visible_controls_views[1]->SetPosition(gfx::Point(
+            mid_window_x - kPrimaryControlSize.width() / 2, primary_control_y));
+
+        visible_controls_views[2]->SetSize(kSecondaryControlSize);
+        visible_controls_views[2]->SetPosition(gfx::Point(
+            mid_window_x + kPrimaryControlSize.width() / 2 + kControlMargin,
+            secondary_control_y));
+      } else {
+        visible_controls_views[1]->SetSize(kSecondaryControlSize);
+        visible_controls_views[1]->SetPosition(
+            gfx::Point(mid_window_x - kSecondaryControlSize.width() / 2,
+                       secondary_control_y));
+
+        visible_controls_views[2]->SetSize(kSecondaryControlSize);
+        visible_controls_views[2]->SetPosition(gfx::Point(
+            mid_window_x + kSecondaryControlSize.width() / 2 + kControlMargin,
+            secondary_control_y));
+      }
+      return;
+    }
+    case 4: {
+      /* | - [ ] [ ] [ ] [ ] - | */
+      visible_controls_views[0]->SetSize(kSecondaryControlSize);
+      visible_controls_views[0]->SetPosition(
+          gfx::Point(mid_window_x - kControlMargin * 3 / 2 -
+                         kSecondaryControlSize.width() * 2,
+                     secondary_control_y));
+
+      visible_controls_views[1]->SetSize(kSecondaryControlSize);
+      visible_controls_views[1]->SetPosition(gfx::Point(
+          mid_window_x - kControlMargin / 2 - kSecondaryControlSize.width(),
+          secondary_control_y));
+
+      visible_controls_views[2]->SetSize(kSecondaryControlSize);
+      visible_controls_views[2]->SetPosition(
+          gfx::Point(mid_window_x + kControlMargin / 2, secondary_control_y));
+
+      visible_controls_views[3]->SetSize(kSecondaryControlSize);
+      visible_controls_views[3]->SetPosition(gfx::Point(
+          mid_window_x + kControlMargin * 3 / 2 + kSecondaryControlSize.width(),
+          secondary_control_y));
+      return;
+    }
+    case 5: {
+      /* | [ ] [ ] [ ] [ ] [ ] | */
+      visible_controls_views[0]->SetSize(kSecondaryControlSize);
+      visible_controls_views[0]->SetPosition(
+          gfx::Point(mid_window_x - kPrimaryControlSize.width() / 2 -
+                         kControlMargin * 2 - kSecondaryControlSize.width() * 2,
+                     secondary_control_y));
+
+      visible_controls_views[1]->SetSize(kSecondaryControlSize);
+      visible_controls_views[1]->SetPosition(
+          gfx::Point(mid_window_x - kPrimaryControlSize.width() / 2 -
+                         kControlMargin - kSecondaryControlSize.width(),
+                     secondary_control_y));
+
+      visible_controls_views[2]->SetSize(kPrimaryControlSize);
+      visible_controls_views[2]->SetPosition(gfx::Point(
+          mid_window_x - kPrimaryControlSize.width() / 2, primary_control_y));
+
+      visible_controls_views[3]->SetSize(kSecondaryControlSize);
+      visible_controls_views[3]->SetPosition(gfx::Point(
+          mid_window_x + kPrimaryControlSize.width() / 2 + kControlMargin,
+          secondary_control_y));
+
+      visible_controls_views[4]->SetSize(kSecondaryControlSize);
+      visible_controls_views[4]->SetPosition(
+          gfx::Point(mid_window_x + kPrimaryControlSize.width() / 2 +
+                         kControlMargin * 2 + kSecondaryControlSize.width(),
+                     secondary_control_y));
+      return;
+    }
   }
-  if (show_previous_track_button_) {
-    previous_track_controls_view_->SetBoundsRect(CalculateControlsBounds(
-        mid_window_x - play_pause_controls_view_->size().width() / 2 -
-            previous_track_controls_view_->GetLastVisibleSize().width() -
-            kControlButtonMargin,
-        previous_track_controls_view_->GetLastVisibleSize()));
-  }
+  DCHECK(false);
 }
 
 gfx::Rect OverlayWindowViews::CalculateControlsBounds(int x,
@@ -545,26 +666,6 @@
       gfx::Point(x, (GetBounds().size().height() - size.height()) / 2), size);
 }
 
-void OverlayWindowViews::UpdateButtonControlsSize() {
-  const gfx::Size window_size = GetBounds().size();
-  int scaled_button_dimension =
-      window_size.width() < window_size.height()
-          ? window_size.width() * kPlayPauseControlRatioToWindow
-          : window_size.height() * kPlayPauseControlRatioToWindow;
-
-  int new_button_dimension =
-      std::max(kMinControlButtonSize, scaled_button_dimension);
-
-  const gfx::Size play_pause_button_size(new_button_dimension,
-                                         new_button_dimension);
-
-  play_pause_controls_view_->SetSize(play_pause_button_size);
-  gfx::Size track_button_size = gfx::ScaleToRoundedSize(
-      play_pause_button_size, kTrackControlRatioToPlayPauseControl);
-  next_track_controls_view_->SetSize(track_button_size);
-  previous_track_controls_view_->SetSize(track_button_size);
-}
-
 bool OverlayWindowViews::IsActive() const {
   return views::Widget::IsActive();
 }
@@ -624,12 +725,21 @@
 }
 
 void OverlayWindowViews::SetAlwaysHidePlayPauseButton(bool is_visible) {
+  if (always_hide_play_pause_button_ == !is_visible)
+    return;
+
   always_hide_play_pause_button_ = !is_visible;
+  UpdateControlsBounds();
 }
 
 void OverlayWindowViews::SetMutedState(MutedState muted_state) {
+  if (muted_state_for_testing_ == muted_state)
+    return;
+
   muted_state_for_testing_ = muted_state;
+  show_mute_button_ = (muted_state != kNoAudio);
   mute_controls_view_->SetMutedState(muted_state);
+  UpdateControlsBounds();
 }
 
 void OverlayWindowViews::SetSkipAdButtonVisibility(bool is_visible) {
@@ -641,7 +751,6 @@
     return;
 
   show_next_track_button_ = is_visible;
-  UpdateButtonControlsSize();
   UpdateControlsBounds();
 }
 
@@ -650,7 +759,6 @@
     return;
 
   show_previous_track_button_ = is_visible;
-  UpdateButtonControlsSize();
   UpdateControlsBounds();
 }
 
@@ -706,8 +814,6 @@
 #if defined(OS_CHROMEOS)
   // Update the positioning of some icons when the window is moved.
   WindowQuadrant quadrant = GetCurrentWindowQuadrant(GetBounds(), controller_);
-  back_to_tab_controls_view_->SetPosition(GetBounds().size(), quadrant);
-  mute_controls_view_->SetPosition(GetBounds().size(), quadrant);
   close_controls_view_->SetPosition(GetBounds().size(), quadrant);
   resize_handle_view_->SetPosition(GetBounds().size(), quadrant);
 #endif
@@ -720,7 +826,6 @@
     UpdateControlsVisibility(false);
 
   // Update the view layers to scale to |new_size|.
-  UpdateButtonControlsSize();
   UpdateLayerBoundsWithLetterboxing(new_size);
 
   views::Widget::OnNativeWidgetSizeChanged(new_size);
@@ -957,10 +1062,6 @@
   return resize_handle_view_->layer();
 }
 
-ui::Layer* OverlayWindowViews::GetControlsParentLayer() {
-  return controls_parent_view_->layer();
-}
-
 void OverlayWindowViews::TogglePlayPause() {
   // Retrieve expected active state based on what command was sent in
   // TogglePlayPause() since the IPC message may not have been propagated
@@ -1013,10 +1114,6 @@
   return resize_handle_view_->origin();
 }
 
-views::View* OverlayWindowViews::controls_parent_view_for_testing() const {
-  return controls_parent_view_.get();
-}
-
 OverlayWindowViews::PlaybackState
 OverlayWindowViews::playback_state_for_testing() const {
   return playback_state_for_testing_;
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.h b/chrome/browser/ui/views/overlay/overlay_window_views.h
index 4607592..be17397 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.h
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.h
@@ -96,7 +96,6 @@
   gfx::Point close_image_position_for_testing() const;
   gfx::Point mute_image_position_for_testing() const;
   gfx::Point resize_handle_position_for_testing() const;
-  views::View* controls_parent_view_for_testing() const;
   OverlayWindowViews::PlaybackState playback_state_for_testing() const;
   OverlayWindowViews::MutedState muted_state_for_testing() const;
   ui::Layer* video_layer_for_testing() const;
@@ -204,17 +203,14 @@
   std::unique_ptr<views::View> window_background_view_;
   std::unique_ptr<views::View> video_view_;
   std::unique_ptr<views::View> controls_scrim_view_;
-  // |controls_parent_view_| is the parent view of play/pause, previous
-  // track and next track control views.
-  std::unique_ptr<views::View> controls_parent_view_;
-  std::unique_ptr<views::BackToTabImageButton> back_to_tab_controls_view_;
-  std::unique_ptr<views::MuteImageButton> mute_controls_view_;
-  std::unique_ptr<views::SkipAdLabelButton> skip_ad_controls_view_;
   std::unique_ptr<views::CloseImageButton> close_controls_view_;
-  std::unique_ptr<views::ResizeHandleButton> resize_handle_view_;
+  std::unique_ptr<views::BackToTabImageButton> back_to_tab_controls_view_;
+  std::unique_ptr<views::TrackImageButton> previous_track_controls_view_;
   std::unique_ptr<views::PlaybackImageButton> play_pause_controls_view_;
   std::unique_ptr<views::TrackImageButton> next_track_controls_view_;
-  std::unique_ptr<views::TrackImageButton> previous_track_controls_view_;
+  std::unique_ptr<views::MuteImageButton> mute_controls_view_;
+  std::unique_ptr<views::SkipAdLabelButton> skip_ad_controls_view_;
+  std::unique_ptr<views::ResizeHandleButton> resize_handle_view_;
 #if defined(OS_CHROMEOS)
   std::unique_ptr<ash::RoundedCornerDecorator> decorator_;
 #endif
@@ -230,6 +226,10 @@
   // used to toggle mute button.
   MutedState muted_state_for_testing_ = kNoAudio;
 
+  // Whether or not the mute button will be shown. This is not the case when
+  // there is no audio track.
+  bool show_mute_button_ = false;
+
   // Whether or not the skip ad button will be shown. This is the
   // case when Media Session "skipad" action is handled by the website.
   bool show_skip_ad_button_ = false;
diff --git a/chrome/browser/ui/views/overlay/playback_image_button.cc b/chrome/browser/ui/views/overlay/playback_image_button.cc
index dbbde00..82c294b 100644
--- a/chrome/browser/ui/views/overlay/playback_image_button.cc
+++ b/chrome/browser/ui/views/overlay/playback_image_button.cc
@@ -14,8 +14,9 @@
 
 namespace {
 
-SkColor kPlaybackIconBackgroundColor = SK_ColorWHITE;
-SkColor kPlaybackIconColor = SK_ColorBLACK;
+SkColor kPlaybackIconColor = SK_ColorWHITE;
+
+const double kPlaybackImageRatio = 9.0 / 10.0;
 
 }  // namespace
 
@@ -25,6 +26,8 @@
     : ImageButton(listener) {
   SetImageAlignment(views::ImageButton::ALIGN_CENTER,
                     views::ImageButton::ALIGN_MIDDLE);
+
+  // Accessibility.
   SetFocusForPlatform();
   const base::string16 playback_accessible_button_label(
       l10n_util::GetStringUTF16(
@@ -33,21 +36,16 @@
   SetInstallFocusRingOnFocus(true);
 }
 
-PlaybackImageButton::~PlaybackImageButton() = default;
-
-void PlaybackImageButton::OnBoundsChanged(const gfx::Rect&) {
+void PlaybackImageButton::OnBoundsChanged(const gfx::Rect& rect) {
   play_image_ = gfx::CreateVectorIcon(vector_icons::kPlayArrowIcon,
-                                      size().width() / 2, kPlaybackIconColor);
+                                      size().width() * kPlaybackImageRatio,
+                                      kPlaybackIconColor);
   pause_image_ = gfx::CreateVectorIcon(vector_icons::kPauseIcon,
-                                       size().width() / 2, kPlaybackIconColor);
+                                       size().width() * kPlaybackImageRatio,
+                                       kPlaybackIconColor);
   replay_image_ = gfx::CreateVectorIcon(vector_icons::kReplayIcon,
-                                        size().width() / 2, kPlaybackIconColor);
-
-  const gfx::ImageSkia background_image_ =
-      gfx::CreateVectorIcon(kPictureInPictureControlBackgroundIcon,
-                            size().width(), kPlaybackIconBackgroundColor);
-  SetBackgroundImage(kPlaybackIconBackgroundColor, &background_image_,
-                     &background_image_);
+                                        size().width() * kPlaybackImageRatio,
+                                        kPlaybackIconColor);
 
   UpdateImageAndTooltipText();
 }
diff --git a/chrome/browser/ui/views/overlay/playback_image_button.h b/chrome/browser/ui/views/overlay/playback_image_button.h
index 8453f28..5a43fe62 100644
--- a/chrome/browser/ui/views/overlay/playback_image_button.h
+++ b/chrome/browser/ui/views/overlay/playback_image_button.h
@@ -14,7 +14,7 @@
 class PlaybackImageButton : public views::ImageButton {
  public:
   explicit PlaybackImageButton(ButtonListener*);
-  ~PlaybackImageButton() override;
+  ~PlaybackImageButton() override = default;
 
   // Show appropriate images based on playback state.
   void SetPlaybackState(const OverlayWindowViews::PlaybackState playback_state);
diff --git a/chrome/browser/ui/views/overlay/resize_handle_button.cc b/chrome/browser/ui/views/overlay/resize_handle_button.cc
index 29fd1e8..72cc587 100644
--- a/chrome/browser/ui/views/overlay/resize_handle_button.cc
+++ b/chrome/browser/ui/views/overlay/resize_handle_button.cc
@@ -17,8 +17,8 @@
 
 namespace {
 
-const int kResizeHandleButtonSize = 36;
-const int kResizeHandleImageSize = 18;
+const int kResizeHandleButtonMargin = 4;
+const int kResizeHandleButtonSize = 16;
 
 constexpr SkColor kResizeHandleIconColor = SK_ColorWHITE;
 
@@ -67,20 +67,23 @@
   // This is determined as the opposite quadrant on the window.
   switch (quadrant) {
     case OverlayWindowViews::WindowQuadrant::kBottomLeft:
-      ImageButton::SetPosition(
-          gfx::Point(size.width() - kResizeHandleButtonSize, 0));
+      ImageButton::SetPosition(gfx::Point(
+          size.width() - kResizeHandleButtonSize - kResizeHandleButtonMargin,
+          kResizeHandleButtonMargin));
       break;
     case OverlayWindowViews::WindowQuadrant::kBottomRight:
-      ImageButton::SetPosition(gfx::Point(0, 0));
+      ImageButton::SetPosition(
+          gfx::Point(kResizeHandleButtonMargin, kResizeHandleButtonMargin));
       break;
     case OverlayWindowViews::WindowQuadrant::kTopLeft:
-      ImageButton::SetPosition(
-          gfx::Point(size.width() - kResizeHandleButtonSize,
-                     size.height() - kResizeHandleButtonSize));
+      ImageButton::SetPosition(gfx::Point(
+          size.width() - kResizeHandleButtonSize - kResizeHandleButtonMargin,
+          size.height() - kResizeHandleButtonSize - kResizeHandleButtonMargin));
       break;
     case OverlayWindowViews::WindowQuadrant::kTopRight:
-      ImageButton::SetPosition(
-          gfx::Point(0, size.height() - kResizeHandleButtonSize));
+      ImageButton::SetPosition(gfx::Point(
+          kResizeHandleButtonMargin,
+          size.height() - kResizeHandleButtonSize - kResizeHandleButtonMargin));
       break;
   }
 
@@ -95,7 +98,7 @@
   current_quadrant_ = quadrant;
 
   gfx::ImageSkia icon = gfx::CreateVectorIcon(
-      kResizeHandleIcon, kResizeHandleImageSize, kResizeHandleIconColor);
+      kResizeHandleIcon, kResizeHandleButtonSize, kResizeHandleIconColor);
   switch (quadrant) {
     case OverlayWindowViews::WindowQuadrant::kBottomLeft:
       SetImageAlignment(views::ImageButton::ALIGN_RIGHT,
diff --git a/chrome/browser/ui/views/overlay/skip_ad_label_button.cc b/chrome/browser/ui/views/overlay/skip_ad_label_button.cc
index bd1d9952..36e947e 100644
--- a/chrome/browser/ui/views/overlay/skip_ad_label_button.cc
+++ b/chrome/browser/ui/views/overlay/skip_ad_label_button.cc
@@ -13,7 +13,7 @@
 
 const int kSkipAdButtonWidth = 72;
 const int kSkipAdButtonHeight = 24;
-const int kSkipAdButtonMarginBottom = 40;
+const int kSkipAdButtonMarginBottom = 48;
 
 constexpr SkColor kSkipAdButtonTextColor = SK_ColorWHITE;
 constexpr SkColor kSkipAdButtonBorderColor = SK_ColorWHITE;
diff --git a/chrome/browser/ui/views/overlay/track_image_button.cc b/chrome/browser/ui/views/overlay/track_image_button.cc
index 3d54f48d..bb9ca4a1 100644
--- a/chrome/browser/ui/views/overlay/track_image_button.cc
+++ b/chrome/browser/ui/views/overlay/track_image_button.cc
@@ -14,7 +14,9 @@
 
 namespace {
 
-SkColor kTrackIconColor = SK_ColorWHITE;
+const int kTrackImageSize = 18;
+
+constexpr SkColor kTrackIconColor = SK_ColorWHITE;
 
 }  // namespace
 
@@ -23,9 +25,11 @@
 TrackImageButton::TrackImageButton(ButtonListener* listener,
                                    const gfx::VectorIcon& icon,
                                    base::string16 label)
-    : ImageButton(listener), icon_(icon) {
+    : ImageButton(listener),
+      image_(gfx::CreateVectorIcon(icon, kTrackImageSize, kTrackIconColor)) {
   SetImageAlignment(views::ImageButton::ALIGN_CENTER,
                     views::ImageButton::ALIGN_MIDDLE);
+  SetImage(views::Button::STATE_NORMAL, image_);
 
   // Accessibility.
   SetFocusForPlatform();
@@ -34,8 +38,6 @@
   SetInstallFocusRingOnFocus(true);
 }
 
-TrackImageButton::~TrackImageButton() = default;
-
 gfx::Size TrackImageButton::GetLastVisibleSize() const {
   return size().IsEmpty() ? last_visible_size_ : size();
 }
@@ -43,9 +45,6 @@
 void TrackImageButton::OnBoundsChanged(const gfx::Rect&) {
   if (!size().IsEmpty())
     last_visible_size_ = size();
-
-  SetImage(views::Button::STATE_NORMAL,
-           gfx::CreateVectorIcon(icon_, size().width() / 2, kTrackIconColor));
 }
 
 void TrackImageButton::ToggleVisibility(bool is_visible) {
diff --git a/chrome/browser/ui/views/overlay/track_image_button.h b/chrome/browser/ui/views/overlay/track_image_button.h
index a67bc8a..95067ad 100644
--- a/chrome/browser/ui/views/overlay/track_image_button.h
+++ b/chrome/browser/ui/views/overlay/track_image_button.h
@@ -20,7 +20,7 @@
   explicit TrackImageButton(ButtonListener*,
                             const gfx::VectorIcon& icon,
                             base::string16 label);
-  ~TrackImageButton() override;
+  ~TrackImageButton() override = default;
 
   // Get button size when visible.
   gfx::Size GetLastVisibleSize() const;
@@ -33,7 +33,7 @@
   void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
 
  private:
-  const gfx::VectorIcon& icon_;
+  const gfx::ImageSkia image_;
 
   // Last visible size of the image button.
   gfx::Size last_visible_size_;
diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc
index 7a22efbd2..04c58fc 100644
--- a/chrome/browser/ui/views/status_bubble_views.cc
+++ b/chrome/browser/ui/views/status_bubble_views.cc
@@ -254,7 +254,7 @@
 
 void StatusBubbleViews::StatusView::Layout() {
   gfx::Rect text_rect(kTextPositionX, 0,
-                      popup_size_.width() - kTextHorizPadding,
+                      popup_size_.width() - kTextHorizPadding - kTextPositionX,
                       popup_size_.height());
   text_rect.Inset(kShadowThickness, kShadowThickness);
   // Make sure the text is aligned to the right on RTL UIs.
diff --git a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
index 00328b9e..281e7e74 100644
--- a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
@@ -56,7 +56,7 @@
 
 // Maximum interval to display.
 constexpr base::TimeDelta kMaxIntervalToDisplay =
-    base::TimeDelta::FromSecondsD(2.0);
+    base::TimeDelta::FromSecondsD(3.0);
 
 base::FilePath GetLastTracingModelPath(Profile* profile) {
   DCHECK(profile);
diff --git a/chrome/browser/ui/webui/policy_ui_handler.cc b/chrome/browser/ui/webui/policy_ui_handler.cc
index 97bf5224..2836de15 100644
--- a/chrome/browser/ui/webui/policy_ui_handler.cc
+++ b/chrome/browser/ui/webui/policy_ui_handler.cc
@@ -105,16 +105,12 @@
   return l10n_util::GetStringUTF16(IDS_POLICY_ASSOCIATION_STATE_UNMANAGED);
 }
 
-void GetStatusFromCore(const policy::CloudPolicyCore* core,
-                       base::DictionaryValue* dict) {
-  const policy::CloudPolicyStore* store = core->store();
-  const policy::CloudPolicyClient* client = core->client();
-  const policy::CloudPolicyRefreshScheduler* refresh_scheduler =
-        core->refresh_scheduler();
-
-  // CloudPolicyStore errors take precedence to show in the status message.
-  // Other errors (such as transient policy fetching problems) get displayed
-  // only if CloudPolicyStore is in STATUS_OK.
+// CloudPolicyStore errors take precedence to show in the status message.
+// Other errors (such as transient policy fetching problems) get displayed
+// only if CloudPolicyStore is in STATUS_OK.
+base::string16 GetPolicyStatusFromStore(
+    const policy::CloudPolicyStore* store,
+    const policy::CloudPolicyClient* client) {
   base::string16 status =
       policy::FormatStoreStatus(store->status(), store->validation_status());
   if (store->status() == policy::CloudPolicyStore::STATUS_OK) {
@@ -123,6 +119,17 @@
     else if (!store->is_managed())
       status = FormatAssociationState(store->policy());
   }
+  return status;
+}
+
+void GetStatusFromCore(const policy::CloudPolicyCore* core,
+                       base::DictionaryValue* dict) {
+  const policy::CloudPolicyStore* store = core->store();
+  const policy::CloudPolicyClient* client = core->client();
+  const policy::CloudPolicyRefreshScheduler* refresh_scheduler =
+      core->refresh_scheduler();
+
+  const base::string16 status = GetPolicyStatusFromStore(store, client);
 
   const em::PolicyData* policy = store->policy();
   std::string client_id = policy ? policy->device_id() : std::string();
@@ -238,7 +245,7 @@
       public policy::CloudPolicyStore::Observer {
  public:
   explicit MachineLevelUserCloudPolicyStatusProvider(
-      policy::MachineLevelUserCloudPolicyStore* store);
+      policy::CloudPolicyCore* core);
   ~MachineLevelUserCloudPolicyStatusProvider() override;
 
   void GetStatus(base::DictionaryValue* dict) override;
@@ -248,7 +255,7 @@
   void OnStoreError(policy::CloudPolicyStore* store) override;
 
  private:
-  policy::MachineLevelUserCloudPolicyStore* store_;
+  policy::CloudPolicyCore* core_;
 
   DISALLOW_COPY_AND_ASSIGN(MachineLevelUserCloudPolicyStatusProvider);
 };
@@ -400,21 +407,23 @@
 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
 
 MachineLevelUserCloudPolicyStatusProvider::
-    MachineLevelUserCloudPolicyStatusProvider(
-        policy::MachineLevelUserCloudPolicyStore* store) {
-  store_ = store;
-  if (store_)
-    store_->AddObserver(this);
+    MachineLevelUserCloudPolicyStatusProvider(policy::CloudPolicyCore* core)
+    : core_(core) {
+  if (core_->store())
+    core_->store()->AddObserver(this);
 }
 
 MachineLevelUserCloudPolicyStatusProvider::
     ~MachineLevelUserCloudPolicyStatusProvider() {
-  if (store_)
-    store_->RemoveObserver(this);
+  if (core_->store())
+    core_->store()->RemoveObserver(this);
 }
 
 void MachineLevelUserCloudPolicyStatusProvider::GetStatus(
     base::DictionaryValue* dict) {
+  policy::CloudPolicyStore* store = core_->store();
+  policy::CloudPolicyClient* client = core_->client();
+
   policy::BrowserDMTokenStorage* dmTokenStorage =
       policy::BrowserDMTokenStorage::Get();
 
@@ -431,12 +440,11 @@
 
     dict->SetString("deviceId", dmTokenStorage->RetrieveClientId());
   }
-  if (store_) {
-    base::string16 status = policy::FormatStoreStatus(
-        store_->status(), store_->validation_status());
+  if (store) {
+    base::string16 status = GetPolicyStatusFromStore(store, client);
 
     dict->SetString("status", status);
-    const em::PolicyData* policy = store_->policy();
+    const em::PolicyData* policy = store->policy();
     if (policy) {
       dict->SetString(
           "timeSinceLastRefresh",
@@ -706,7 +714,7 @@
   if (manager) {
     machine_status_provider_ =
         std::make_unique<MachineLevelUserCloudPolicyStatusProvider>(
-            manager->store());
+            manager->core());
   }
 #endif  // !defined(OS_ANDROID)
 #endif  // defined(OS_CHROMEOS)
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 d1badaaf..be89c21 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -525,6 +525,9 @@
     // Chrome window in incognito mode.
     params.SetBoolean("dontResizeNonEmbeddedPages", true);
 
+    // Scrape the SAML password if possible.
+    params.SetBoolean("extractSamlPasswordAttributes", true);
+
     GURL windows_url = GaiaUrls::GetInstance()->embedded_setup_windows_url();
     // Redirect to specified gaia endpoint path for GCPW:
     std::string windows_endpoint_path = windows_url.path().substr(1);
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/BUILD.gn b/chrome/chrome_cleaner/parsers/shortcut_parser/target/BUILD.gn
index cd2c923..fb0f2f4 100644
--- a/chrome/chrome_cleaner/parsers/shortcut_parser/target/BUILD.gn
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/BUILD.gn
@@ -1,6 +1,7 @@
 # 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.
+import("//testing/libfuzzer/fuzzer_test.gni")
 
 static_library("lnk_parser") {
   sources = [
@@ -14,6 +15,20 @@
   ]
 }
 
+fuzzer_test("lnk_parser_fuzzer") {
+  sources = [
+    "lnk_parser_fuzzer.cc",
+  ]
+
+  deps = [
+    ":lnk_parser",
+    "//base:base",
+    "//base/test:test_support",
+  ]
+
+  seed_corpus = "data/lnk_parser_fuzzer"
+}
+
 source_set("unittest_sources") {
   testonly = true
 
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/Network Share Test.lnk b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/Network Share Test.lnk
new file mode 100644
index 0000000..bdddedd1
--- /dev/null
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/Network Share Test.lnk
Binary files differ
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/New folder - Shortcut.lnk b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/New folder - Shortcut.lnk
new file mode 100644
index 0000000..5168014
--- /dev/null
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/New folder - Shortcut.lnk
Binary files differ
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/long_name.lnk b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/long_name.lnk
new file mode 100644
index 0000000..53e16c3
--- /dev/null
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/long_name.lnk
Binary files differ
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/options.lnk b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/options.lnk
new file mode 100644
index 0000000..a9972dd1
--- /dev/null
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/options.lnk
Binary files differ
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/regular.lnk b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/regular.lnk
new file mode 100644
index 0000000..e79879a2
--- /dev/null
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/data/lnk_parser_fuzzer/regular.lnk
Binary files differ
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.cc b/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.cc
index 408a45b..3d04668 100644
--- a/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.cc
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.cc
@@ -211,42 +211,10 @@
 
 }  // namespace internal
 
-// Please note that the documentation used to write this parser was obtained
-// from the following link:
-// https://msdn.microsoft.com/en-us/library/dd871305.aspx
-mojom::LnkParsingResult ParseLnk(base::win::ScopedHandle file_handle,
-                                 ParsedLnkFile* parsed_shortcut) {
+mojom::LnkParsingResult internal::ParseLnkBytes(
+    std::vector<BYTE> file_buffer,
+    ParsedLnkFile* parsed_shortcut) {
   DCHECK(parsed_shortcut);
-
-  if (!file_handle.IsValid()) {
-    LOG(ERROR) << "Invalid File Handle";
-    return mojom::LnkParsingResult::INVALID_HANDLE;
-  }
-
-  base::File lnk_file(file_handle.Take());
-  int64_t lnk_file_size = lnk_file.GetLength();
-  if (lnk_file_size <= 0) {
-    LOG(ERROR) << "Error getting file size";
-    return mojom::LnkParsingResult::INVALID_LNK_FILE_SIZE;
-  } else if (lnk_file_size >= kMaximumFileSize) {
-    LOG(ERROR) << "Unexpectedly large file size: " << lnk_file_size;
-    return mojom::LnkParsingResult::INVALID_LNK_FILE_SIZE;
-  }
-
-  std::vector<BYTE> file_buffer(lnk_file_size);
-  int bytes_read = lnk_file.Read(
-      /*offset=*/0, reinterpret_cast<char*>(file_buffer.data()), lnk_file_size);
-  if (bytes_read == -1) {
-    LOG(ERROR) << "Error reading lnk file";
-    return mojom::LnkParsingResult::READING_ERROR;
-  }
-
-  if (bytes_read != lnk_file_size) {
-    LOG(ERROR) << "read less bytes than the actual file size, bytes read: "
-               << bytes_read << " file size: " << lnk_file_size;
-    return mojom::LnkParsingResult::READING_ERROR;
-  }
-
   // This variable is used to keep track which part of the buffer we are
   // currently parsing, please note that its value will be modified in all
   // of the function it is passed as parameter.
@@ -380,4 +348,41 @@
   return mojom::LnkParsingResult::SUCCESS;
 }
 
+// Please note that the documentation used to write this parser was obtained
+// from the following link:
+// https://msdn.microsoft.com/en-us/library/dd871305.aspx
+mojom::LnkParsingResult ParseLnk(base::win::ScopedHandle file_handle,
+                                 ParsedLnkFile* parsed_shortcut) {
+  if (!file_handle.IsValid()) {
+    LOG(ERROR) << "Invalid File Handle";
+    return mojom::LnkParsingResult::INVALID_HANDLE;
+  }
+
+  base::File lnk_file(file_handle.Take());
+  int64_t lnk_file_size = lnk_file.GetLength();
+  if (lnk_file_size <= 0) {
+    LOG(ERROR) << "Error getting file size";
+    return mojom::LnkParsingResult::INVALID_LNK_FILE_SIZE;
+  } else if (lnk_file_size >= kMaximumFileSize) {
+    LOG(ERROR) << "Unexpectedly large file size: " << lnk_file_size;
+    return mojom::LnkParsingResult::INVALID_LNK_FILE_SIZE;
+  }
+
+  std::vector<BYTE> file_buffer(lnk_file_size);
+  int bytes_read = lnk_file.Read(
+      /*offset=*/0, reinterpret_cast<char*>(file_buffer.data()), lnk_file_size);
+  if (bytes_read == -1) {
+    LOG(ERROR) << "Error reading lnk file";
+    return mojom::LnkParsingResult::READING_ERROR;
+  }
+
+  if (bytes_read != lnk_file_size) {
+    LOG(ERROR) << "read less bytes than the actual file size, bytes read: "
+               << bytes_read << " file size: " << lnk_file_size;
+    return mojom::LnkParsingResult::READING_ERROR;
+  }
+
+  return internal::ParseLnkBytes(file_buffer, parsed_shortcut);
+}
+
 }  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.h b/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.h
index 945cba83..23cc661 100644
--- a/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.h
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.h
@@ -15,6 +15,8 @@
 
 namespace chrome_cleaner {
 
+struct ParsedLnkFile;
+
 namespace internal {
 
 // Auxiliary structures for the shortcut parsing.
@@ -61,6 +63,9 @@
     std::vector<BYTE>* file_buffer,
     DWORD* output_offset);
 
+mojom::LnkParsingResult ParseLnkBytes(std::vector<BYTE> file_buffer,
+                                      ParsedLnkFile* parsed_shortcut);
+
 }  // namespace internal
 
 struct ParsedLnkFile {
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser_fuzzer.cc b/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser_fuzzer.cc
new file mode 100644
index 0000000..5d38560
--- /dev/null
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser_fuzzer.cc
@@ -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.
+
+#include <stddef.h>
+#include <stdint.h>
+#include <windows.h>
+#include <memory>
+#include <string>
+
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/fuzzed_data_provider.h"
+
+#include "chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser.h"
+
+struct Environment {
+  Environment() { logging::SetMinLogLevel(logging::LOG_FATAL); }
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static Environment env;
+
+  base::FuzzedDataProvider data_provider(data, size);
+  std::vector<BYTE> file_buffer = data_provider.ConsumeRemainingBytes();
+
+  chrome_cleaner::ParsedLnkFile parsed_shortcut;
+
+  (void)chrome_cleaner::internal::ParseLnkBytes(file_buffer, &parsed_shortcut);
+  return 0;
+}
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 038cd77..2f396941 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -542,9 +542,6 @@
 const base::Feature kLoadBrokenImagesFromContextMenu{
     "LoadBrokenImagesFromContextMenu", base::FEATURE_DISABLED_BY_DEFAULT};
 
-const base::Feature kSafeSearchUrlReporting{"SafeSearchUrlReporting",
-                                            base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Controls whether the user is prompted when sites request attestation.
 const base::Feature kSecurityKeyAttestationPrompt{
     "SecurityKeyAttestationPrompt", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index c824d498..fdba3fac 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -350,9 +350,6 @@
 extern const base::Feature kLoadBrokenImagesFromContextMenu;
 
 COMPONENT_EXPORT(CHROME_FEATURES)
-extern const base::Feature kSafeSearchUrlReporting;
-
-COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kSecurityKeyAttestationPrompt;
 
 #if !defined(OS_ANDROID)
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 8127926..f4431a6 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4702,7 +4702,6 @@
       "../browser/supervised_user/child_accounts/child_account_service_unittest.cc",
       "../browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc",
       "../browser/supervised_user/child_accounts/permission_request_creator_apiary_unittest.cc",
-      "../browser/supervised_user/experimental/safe_search_url_reporter_unittest.cc",
       "../browser/supervised_user/kids_management_url_checker_client_unittest.cc",
       "../browser/supervised_user/supervised_user_pref_store_unittest.cc",
       "../browser/supervised_user/supervised_user_service_unittest.cc",
@@ -5159,6 +5158,7 @@
     # Runtime dependencies
     data_deps = [
       "//ppapi:ppapi_tests",
+      "//testing/buildbot/filters:interactive_ui_tests_filters",
       "//third_party/mesa_headers",
     ]
 
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 9211868..a475a9b 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -900,6 +900,67 @@
         elapsed_time = events[i]['time'] - events[i-1]['time']
         self.assertGreaterEqual(elapsed_time, 200)
 
+  def testReleaseActions(self):
+    self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
+    self._driver.ExecuteScript(
+        '''
+        document.body.innerHTML
+          = "<input id='target' type='text' style='width:200px; height:200px'>";
+        window.events = [];
+        const recordKeyEvent = event => {
+          window.events.push(
+              {type: event.type, code: event.code});
+        };
+        const recordMouseEvent = event => {
+          window.events.push(
+              {type: event.type, x: event.clientX, y: event.clientY});
+        };
+        const target = document.getElementById('target');
+        target.addEventListener('keydown', recordKeyEvent);
+        target.addEventListener('keyup', recordKeyEvent);
+        target.addEventListener('mousedown', recordMouseEvent);
+        target.addEventListener('mouseup', recordMouseEvent);
+        ''')
+
+    # Move mouse to (50, 50), press a mouse button, and press a key.
+    self._driver.PerformActions({'actions': [
+        {
+            'type': 'pointer',
+            'id': 'mouse',
+            'actions': [
+                {'type': 'pointerMove', 'x': 50, 'y': 50},
+                {'type': 'pointerDown', "button": 0}
+            ]
+        },
+        {
+            'type': 'key',
+            'id': 'key',
+            'actions': [
+                {'type': 'pause'},
+                {'type': 'pause'},
+                {'type': 'keyDown', 'value': 'a'}
+            ]
+        }
+    ]})
+
+    events = self._driver.ExecuteScript('return window.events')
+    self.assertEquals(2, len(events))
+    self.assertEquals('mousedown', events[0]['type'])
+    self.assertEquals(50, events[0]['x'])
+    self.assertEquals(50, events[0]['y'])
+    self.assertEquals('keydown', events[1]['type'])
+    self.assertEquals('KeyA', events[1]['code'])
+
+    self._driver.ReleaseActions()
+
+    events = self._driver.ExecuteScript('return window.events')
+    self.assertEquals(4, len(events))
+    self.assertEquals('keyup', events[2]['type'])
+    self.assertEquals('KeyA', events[2]['code'])
+    self.assertEquals('mouseup', events[3]['type'])
+    self.assertEquals(50, events[3]['x'])
+    self.assertEquals(50, events[3]['y'])
+
   def testPageLoadStrategyIsNormalByDefault(self):
     self.assertEquals('normal',
                       self._driver.capabilities['pageLoadStrategy'])
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index 081f9752..fe8529e 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -1089,11 +1089,11 @@
       // enum KeyModifierMask.
       tmp_state.SetInteger("modifiers", 0);
     } else if (type == "pointer") {
-      std::unique_ptr<base::ListValue> pressed(new base::ListValue);
       int x = 0;
       int y = 0;
 
-      tmp_state.SetList("pressed", std::move(pressed));
+      // "pressed" is stored as a bitmask of pointer buttons.
+      tmp_state.SetInteger("pressed", 0);
       tmp_state.SetString("subtype", pointer_type);
 
       tmp_state.SetInteger("x", x);
@@ -1508,6 +1508,17 @@
           event.click_count = session->click_count;
         }
         dispatch_mouse_events.push_back(event);
+        if (event.type == kPressedMouseEventType) {
+          session->input_cancel_list.emplace_back(mouse_input_states[j], &event,
+                                                  nullptr, nullptr);
+          mouse_input_states[j]->SetInteger(
+              "pressed", mouse_input_states[j]->FindKey("pressed")->GetInt() |
+                             (1 << event.button));
+        } else if (event.type == kReleasedMouseEventType) {
+          mouse_input_states[j]->SetInteger(
+              "pressed", mouse_input_states[j]->FindKey("pressed")->GetInt() &
+                             ~(1 << event.button));
+        }
       }
     }
     if (dispatch_mouse_events.size() > 0) {
@@ -1543,6 +1554,13 @@
         }
         if (event.dispatch)
           dispatch_touch_events.push_back(event);
+        if (event.type == kTouchStart) {
+          session->input_cancel_list.emplace_back(touch_input_states[j],
+                                                  nullptr, &event, nullptr);
+          touch_input_states[j]->SetInteger("pressed", 1);
+        } else if (event.type == kTouchEnd) {
+          touch_input_states[j]->SetInteger("pressed", 0);
+        }
       }
     }
     if (dispatch_touch_events.size() > 0) {
@@ -1574,8 +1592,6 @@
                              const base::DictionaryValue& params,
                              std::unique_ptr<base::Value>* value,
                              Timeout* timeout) {
-  // TODO(https://crbug.com/chromedriver/1897): Process "input cancel list" for
-  // mouse and touch events.
   for (auto it = session->input_cancel_list.rbegin();
        it != session->input_cancel_list.rend(); ++it) {
     if (it->key_event) {
@@ -1585,6 +1601,20 @@
         continue;
       web_view->DispatchKeyEvents({*it->key_event});
       pressed->Remove(it->key_event->key, nullptr);
+    } else if (it->mouse_event) {
+      int pressed = it->input_state->FindKey("pressed")->GetInt();
+      int button_mask = 1 << it->mouse_event->button;
+      if ((pressed & button_mask) == 0)
+        continue;
+      web_view->DispatchMouseEvents({*it->mouse_event},
+                                    session->GetCurrentFrameId());
+      it->input_state->SetInteger("pressed", pressed & ~button_mask);
+    } else if (it->touch_event) {
+      int pressed = it->input_state->FindKey("pressed")->GetInt();
+      if (pressed == 0)
+        continue;
+      web_view->DispatchTouchEvents({*it->touch_event});
+      it->input_state->SetInteger("pressed", 0);
     }
   }
 
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 6edb675a..f09e0a8e 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3079,6 +3079,18 @@
     ]
   },
 
+  "DockedMagnifierEnabled": {
+    "os": ["chromeos"],
+    "test_policy": { "DockedMagnifierEnabled": true },
+    "pref_mappings": [
+      { "pref": "ash.docked_magnifier.enabled",
+        "indicator_tests": [
+          { "policy": { "DockedMagnifierEnabled": true } }
+        ]
+      }
+    ]
+  },
+
   "SpokenFeedbackEnabled": {
     "os": ["chromeos"],
     "test_policy": { "SpokenFeedbackEnabled": true },
diff --git a/chrome/test/data/webui/polymer_browser_test_base.js b/chrome/test/data/webui/polymer_browser_test_base.js
index 60b03af5..c8d94c2 100644
--- a/chrome/test/data/webui/polymer_browser_test_base.js
+++ b/chrome/test/data/webui/polymer_browser_test_base.js
@@ -24,6 +24,14 @@
   browsePreload: 'chrome://chrome-urls/',
 
   /**
+   * The name of the custom element under test. Should be overridden by
+   * subclasses that are using the HTML imports polyfill and need to wait for
+   * a custom element to be defined before starting the test.
+   * @type {?string}
+   */
+  customElementName: null,
+
+  /**
    * The mocha adapter assumes all tests are async.
    * @override
    * @final
@@ -85,6 +93,20 @@
         throw e;
       }
     };
+
+    if (typeof HTMLImports !== 'undefined') {
+      suiteSetup(() => {
+        return new Promise(resolve => {
+                 HTMLImports.whenReady(resolve);
+               })
+            .then(() => {
+              const customElementName = this.customElementName;
+              if (customElementName) {
+                return customElements.whenDefined(customElementName);
+              }
+            });
+      });
+    }
   },
 
   /** @override */
diff --git a/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js b/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js
index 73df732c..01251b9 100644
--- a/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js
+++ b/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js
@@ -21,11 +21,24 @@
     ];
   }
 
+  /** @override */
+  get loaderFile() {
+    return 'subpage_loader.html';
+  }
+
   // The name of the mocha suite. Should be overridden by subclasses.
   get suiteName() {
     return null;
   }
 
+  // The name of the custom element under test. Should be overridden by
+  // subclasses that are not directly loading the URL of a custom element.
+  get customElementName() {
+    const r = /chrome\:\/\/print\/([a-zA-Z-_]+)\/([a-zA-Z-_]+)\.html/;
+    const result = r.exec(this.browsePreload);
+    return 'print-preview-' + result[2].replace(/_/gi, '-');
+  }
+
   /** @param {string} testName The name of the test to run. */
   runMochaTest(testName) {
     runMochaTest(this.suiteName, testName);
diff --git a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
index 7ba4dee2..e439493 100644
--- a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
+++ b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
@@ -42,22 +42,6 @@
   runMochaTest(testName) {
     runMochaTest(this.suiteName, testName);
   }
-
-  /** @override */
-  setUp() {
-    super.setUp();
-    suiteSetup(() => {
-      return new Promise(resolve => {
-               HTMLImports.whenReady(resolve);
-             })
-          .then(() => {
-            const customElementName = this.customElementName;
-            if (customElementName) {
-              return customElements.whenDefined(customElementName);
-            }
-          });
-    });
-  }
 };
 
 PrintPreviewAppTest = class extends PrintPreviewTest {
diff --git a/chrome/test/vr/perf/latency/webvr_latency_test.py b/chrome/test/vr/perf/latency/webvr_latency_test.py
index 948ff8af..d58c67b 100644
--- a/chrome/test/vr/perf/latency/webvr_latency_test.py
+++ b/chrome/test/vr/perf/latency/webvr_latency_test.py
@@ -105,13 +105,13 @@
     for device_type, vendor_ids in VENDOR_IDS.iteritems():
       devices = GetTtyDevices(r'ttyACM\d+', vendor_ids)
       if devices:
-        if device_type is 'arduino':
+        if device_type == 'arduino':
           if len(devices) != 1:
             raise RuntimeError(
                 'Found %d arduino devices, expected 1' % len(devices))
           self.robot_arm = arduino_arm.RobotArmArduino(devices[0])
           break
-        elif device_type is 'maestro':
+        elif device_type == 'maestro':
           # The Maestro controllers open up two serial ports. We only use one,
           # but if we don't detect both, that's an indication that something is
           # wrong.
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc
index 8772374..0578416 100644
--- a/chrome/updater/updater.cc
+++ b/chrome/updater/updater.cc
@@ -55,10 +55,10 @@
   const auto thread_pool_init_params =
       std::make_unique<base::ThreadPool::InitParams>(
           base::ThreadGroupParams(
-              base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
+              base::RecommendedMaxNumberOfThreadsInThreadGroup(3, 8, 0.1, 0),
               base::TimeDelta::FromSeconds(30)),
           base::ThreadGroupParams(
-              base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0),
+              base::RecommendedMaxNumberOfThreadsInThreadGroup(8, 32, 0.3, 0),
               base::TimeDelta::FromSeconds(30)));
   base::ThreadPool::GetInstance()->Start(*thread_pool_init_params);
 }
diff --git a/chromecast/browser/cast_permission_manager.cc b/chromecast/browser/cast_permission_manager.cc
index 3e61650..b358fc3b 100644
--- a/chromecast/browser/cast_permission_manager.cc
+++ b/chromecast/browser/cast_permission_manager.cc
@@ -22,9 +22,9 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& origin,
     bool user_gesture,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) {
   LOG(INFO) << __FUNCTION__ << ": " << static_cast<int>(permission);
-  callback.Run(blink::mojom::PermissionStatus::GRANTED);
+  std::move(callback).Run(blink::mojom::PermissionStatus::GRANTED);
   return content::PermissionController::kNoPendingOperation;
 }
 
@@ -33,9 +33,9 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<
-        void(const std::vector<blink::mojom::PermissionStatus>&)>& callback) {
-  callback.Run(std::vector<blink::mojom::PermissionStatus>(
+    base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)>
+        callback) {
+  std::move(callback).Run(std::vector<blink::mojom::PermissionStatus>(
       permissions.size(), blink::mojom::PermissionStatus::GRANTED));
   return content::PermissionController::kNoPendingOperation;
 }
@@ -67,7 +67,7 @@
     content::PermissionType permission,
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
   return content::PermissionController::kNoPendingOperation;
 }
 
diff --git a/chromecast/browser/cast_permission_manager.h b/chromecast/browser/cast_permission_manager.h
index 585f998..564ac2b 100644
--- a/chromecast/browser/cast_permission_manager.h
+++ b/chromecast/browser/cast_permission_manager.h
@@ -18,20 +18,19 @@
   ~CastPermissionManager() override;
 
   // content::PermissionControllerDelegate implementation:
-  int RequestPermission(
-      content::PermissionType permission,
-      content::RenderFrameHost* render_frame_host,
-      const GURL& requesting_origin,
-      bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
-      override;
+  int RequestPermission(content::PermissionType permission,
+                        content::RenderFrameHost* render_frame_host,
+                        const GURL& requesting_origin,
+                        bool user_gesture,
+                        base::OnceCallback<void(blink::mojom::PermissionStatus)>
+                            callback) override;
   int RequestPermissions(
       const std::vector<content::PermissionType>& permission,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<
-          void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
+      base::OnceCallback<
+          void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
       override;
   void ResetPermission(content::PermissionType permission,
                        const GURL& requesting_origin,
@@ -48,7 +47,7 @@
       content::PermissionType permission,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
+      base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
       override;
   void UnsubscribePermissionStatusChange(int subscription_id) override;
 
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index dd1a57f..e39d2fdb 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -629,6 +629,7 @@
     "//third_party/libaddressinput:test_support",
     "//third_party/libaddressinput:util",
     "//third_party/libphonenumber",
+    "//third_party/re2:re2",
     "//ui/base",
     "//url",
   ]
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc
index 1b9a042..fd79ad2 100644
--- a/components/autofill/core/browser/autofill_download_manager.cc
+++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -60,7 +60,7 @@
     {3314445, 3314448}, {3314854, 3314883},
 };
 
-const size_t kMaxQueryGetSize = 1400;  // 1.25KB
+const size_t kMaxQueryGetSize = 1400;  // 1.25 KiB
 const size_t kAutofillDownloadManagerMaxFormCacheSize = 16;
 const size_t kMaxFieldsPerQueryRequest = 100;
 
@@ -448,16 +448,22 @@
   return upload_request.SerializeToString(payload);
 }
 
-// Gets an API method URL given its type (query or upload) and an optional
-// resource ID.
+// Gets an API method URL given its type (query or upload), an optional
+// resource ID, and the HTTP method to be used.
 // Example usage:
-//   * GetAPIMethodUrl(REQUEST_QUERY, "1234") will return "/v1/pages/1234".
-//   * GetAPIMethodUrl(REQUEST_UPLOAD, "") will return "/v1/forms:vote".
+// * GetAPIMethodUrl(REQUEST_QUERY, "1234", "GET") will return "/v1/pages/1234".
+// * GetAPIMethodUrl(REQUEST_QUERY, "1234", "POST") will return "/v1/pages:get".
+// * GetAPIMethodUrl(REQUEST_UPLOAD, "", "POST") will return "/v1/forms:vote".
 std::string GetAPIMethodUrl(AutofillDownloadManager::RequestType type,
-                            base::StringPiece resource_id) {
+                            base::StringPiece resource_id,
+                            base::StringPiece method) {
   const char* api_method_url;
   if (type == AutofillDownloadManager::REQUEST_QUERY) {
-    api_method_url = "/v1/pages";
+    if (method == "POST") {
+      api_method_url = "/v1/pages:get";
+    } else {
+      api_method_url = "/v1/pages";
+    }
   } else if (type == AutofillDownloadManager::REQUEST_UPLOAD) {
     api_method_url = "/v1/forms:vote";
   } else {
@@ -471,6 +477,35 @@
   return base::StrCat({api_method_url, "/", resource_id});
 }
 
+// Gets HTTP body payload for API POST request.
+std::string GetAPIBodyPayload(const std::string& payload,
+                              AutofillDownloadManager::RequestType type) {
+  // Don't do anything for payloads not related to Query.
+  if (type != AutofillDownloadManager::REQUEST_QUERY) {
+    return payload;
+  }
+  // Wrap query payload in a request proto to interface with API Query method.
+  AutofillPageResourceQueryRequest request;
+  request.set_serialized_request(payload);
+  std::string new_payload;
+  DCHECK(request.SerializeToString(&new_payload))
+      << "could not serialize AutofillPageResourceQueryRequest payload";
+  return new_payload;
+}
+
+// Gets the data payload for API Query (POST and GET).
+bool GetAPIQueryPayload(const AutofillQueryContents& query,
+                        std::string* payload) {
+  std::string serialized_query;
+  if (!CreateApiRequestFromLegacyRequest(query).SerializeToString(
+          &serialized_query)) {
+    return false;
+  }
+  base::Base64UrlEncode(serialized_query,
+                        base::Base64UrlEncodePolicy::INCLUDE_PADDING, payload);
+  return true;
+}
+
 }  // namespace
 
 struct AutofillDownloadManager::FormRequestData {
@@ -542,10 +577,8 @@
 
   // Get the query request payload.
   std::string payload;
-  bool is_payload_serialized =
-      UseApi()
-          ? CreateApiRequestFromLegacyRequest(query).SerializeToString(&payload)
-          : query.SerializeToString(&payload);
+  bool is_payload_serialized = UseApi() ? GetAPIQueryPayload(query, &payload)
+                                        : query.SerializeToString(&payload);
   if (!is_payload_serialized) {
     return false;
   }
@@ -674,31 +707,27 @@
   // ID of the resource to add to the API request URL. Nothing will be added if
   // |resource_id| is empty.
   std::string resource_id;
+  std::string method = "POST";
 
-  // Get the resource id of corresponding webpage when doing a query request.
   if (request_data.request_type == AutofillDownloadManager::REQUEST_QUERY) {
-    if (request_data.payload.length() <= kMaxQueryGetSize) {
-      base::Base64UrlEncode(request_data.payload,
-                            base::Base64UrlEncodePolicy::INCLUDE_PADDING,
-                            &resource_id);
+    if (request_data.payload.length() <= kMaxAPIQueryGetSize) {
+      resource_id = request_data.payload;
+      method = "GET";
+      UMA_HISTOGRAM_BOOLEAN("Autofill.Query.ApiUrlIsTooLong", false);
+    } else {
+      UMA_HISTOGRAM_BOOLEAN("Autofill.Query.ApiUrlIsTooLong", true);
     }
-    // Query method is always GET (represented by 0) with API.
-    UMA_HISTOGRAM_BOOLEAN("Autofill.Query.Method", 0);
+    UMA_HISTOGRAM_BOOLEAN("Autofill.Query.Method", (method == "GET") ? 0 : 1);
   }
 
   // Make the canonical URL to query the API, e.g.,
   // https://autofill.googleapis.com/v1/forms/1234?alt=proto.
   GURL url = autofill_server_url_.Resolve(
-      GetAPIMethodUrl(request_data.request_type, resource_id));
+      GetAPIMethodUrl(request_data.request_type, resource_id, method));
 
   // Add the query parameter to set the response format to a serialized proto.
   url = net::AppendQueryParameter(url, "alt", "proto");
 
-  // Determine the HTTP method that should be used.
-  std::string method =
-      (request_data.request_type == AutofillDownloadManager::REQUEST_QUERY)
-          ? "GET"
-          : "POST";
   return std::make_tuple(std::move(url), std::move(method));
 }
 
@@ -714,6 +743,14 @@
       UseApi() ? GetRequestURLAndMethodForApi(request_data)
                : GetRequestURLAndMethod(request_data);
 
+  // Track the URL length for GET queries because the URL length can be in the
+  // thousands when rich metadata is enabled.
+  if (request_data.request_type == AutofillDownloadManager::REQUEST_QUERY &&
+      method == "GET") {
+    UMA_HISTOGRAM_COUNTS_100000("Autofill.Query.GetUrlLength",
+                                request_url.spec().length());
+  }
+
   auto resource_request = std::make_unique<network::ResourceRequest>();
   resource_request->url = request_url;
   resource_request->load_flags =
@@ -750,10 +787,14 @@
   simple_loader->SetAllowHttpErrorResults(true);
 
   if (method == "POST") {
-    const std::string content_type =
+    const std::string& content_type =
         UseApi() ? "application/x-protobuf" : "text/proto";
+    const std::string& payload =
+        UseApi()
+            ? GetAPIBodyPayload(request_data.payload, request_data.request_type)
+            : request_data.payload;
     // Attach payload data and add data format header.
-    simple_loader->AttachStringForUpload(request_data.payload, content_type);
+    simple_loader->AttachStringForUpload(payload, content_type);
   }
 
   // Transfer ownership of the loader into url_loaders_. Temporarily hang
diff --git a/components/autofill/core/browser/autofill_download_manager.h b/components/autofill/core/browser/autofill_download_manager.h
index f38c3ae8..0a49974 100644
--- a/components/autofill/core/browser/autofill_download_manager.h
+++ b/components/autofill/core/browser/autofill_download_manager.h
@@ -31,6 +31,8 @@
 class AutofillDriver;
 class FormStructure;
 
+const size_t kMaxAPIQueryGetSize = 10240;  // 10 KiB
+
 // A helper to make sure that tests which modify the set of active autofill
 // experiments do not interfere with one another.
 struct ScopedActiveAutofillExperiments {
diff --git a/components/autofill/core/browser/autofill_download_manager_unittest.cc b/components/autofill/core/browser/autofill_download_manager_unittest.cc
index b6c34b6..8015361 100644
--- a/components/autofill/core/browser/autofill_download_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -52,6 +52,7 @@
 #include "services/network/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/re2/src/re2/re2.h"
 #include "url/third_party/mozilla/url_parse.h"
 
 using base::UTF8ToUTF16;
@@ -117,6 +118,35 @@
   return true;
 }
 
+bool GetAutofillPageResourceQueryRequestFromRequest(
+    network::TestURLLoaderFactory::PendingRequest* loader_request,
+    AutofillPageResourceQueryRequest* query_request) {
+  if (loader_request->request.request_body == nullptr) {
+    return false;
+  }
+
+  std::string request_body_content = GetStringFromDataElements(
+      loader_request->request.request_body->elements());
+  if (!query_request->ParseFromString(request_body_content)) {
+    return false;
+  }
+  return true;
+}
+
+bool DeserializeAutofillPageQueryRequest(base::StringPiece serialized_content,
+                                         AutofillPageQueryRequest* request) {
+  std::string decoded_content;
+  if (!base::Base64UrlDecode(serialized_content,
+                             base::Base64UrlDecodePolicy::REQUIRE_PADDING,
+                             &decoded_content)) {
+    return false;
+  }
+  if (!request->ParseFromString(decoded_content)) {
+    return false;
+  }
+  return true;
+}
+
 }  // namespace
 
 // This tests AutofillDownloadManager. AutofillDownloadManagerTest implements
@@ -499,22 +529,150 @@
   // Inspect the request that the test URL loader sent.
   network::TestURLLoaderFactory::PendingRequest* request =
       test_url_loader_factory_.GetPendingRequest(0);
-  // This is the URL we expect to query the API. The sub-path right after
-  // "/page" corresponds to the serialized AutofillPageQueryRequest proto (that
-  // we filled forms in) encoded in base64. The Autofill
-  // https://clients1.google.com/ domain URL corresponds to the default domain
-  // used by the download manager.
-  const std::string expected_url = {
-      "https://clients1.google.com/v1/pages/"
-      "Chc2LjEuMTcxNS4xNDQyL2VuIChHR0xMKRIlCU9O84MyjH9NEgsNeu"
-      "FP4BIAGgAiABILDZxOStASABoAIgAaAA==?"
-      "alt=proto"};
-  EXPECT_EQ(request->request.url, expected_url);
-  std::string api_key_header_value;
-  EXPECT_TRUE(request->request.headers.GetHeader("X-Goog-Api-Key",
-                                                 &api_key_header_value));
-  EXPECT_EQ(api_key_header_value, "dummykey");
 
+  // Verify request URL and the data payload it carries.
+  {
+    // This is the URL we expect to query the API. The sub-path right after
+    // "/page" corresponds to the serialized AutofillPageQueryRequest proto
+    // (that we filled forms in) encoded in base64. The Autofill
+    // https://clients1.google.com/ domain URL corresponds to the default domain
+    // used by the download manager, which is invalid, but good for testing.
+    const std::string expected_url =
+        R"(https://clients1.google.com/v1/pages/(.+)\?alt=proto)";
+    std::string encoded_request;
+    ASSERT_TRUE(re2::RE2::FullMatch(request->request.url.spec(), expected_url,
+                                    &encoded_request));
+    AutofillPageQueryRequest request_content;
+    ASSERT_TRUE(
+        DeserializeAutofillPageQueryRequest(encoded_request, &request_content));
+    // Verify form content.
+    ASSERT_EQ(request_content.forms().size(), 1);
+    EXPECT_EQ(request_content.forms(0).signature(),
+              form_structures[0]->form_signature());
+    // Verify field content.
+    ASSERT_EQ(request_content.forms(0).fields().size(), 2);
+    EXPECT_EQ(request_content.forms(0).fields(0).signature(),
+              form_structures[0]->field(0)->GetFieldSignature());
+    EXPECT_EQ(request_content.forms(0).fields(1).signature(),
+              form_structures[0]->field(1)->GetFieldSignature());
+  }
+
+  // Verify API key header.
+  {
+    std::string header_value;
+    EXPECT_TRUE(
+        request->request.headers.GetHeader("X-Goog-Api-Key", &header_value));
+    EXPECT_EQ(header_value, "dummykey");
+  }
+  // Verify binary response header.
+  {
+    std::string header_value;
+    ASSERT_TRUE(request->request.headers.GetHeader(
+        "X-Goog-Encode-Response-If-Executable", &header_value));
+    EXPECT_EQ(header_value, "base64");
+  }
+
+  // Verify response.
+  test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
+      request, "dummy response");
+  // Upon reception of a suggestions query, we expect OnLoadedServerPredictions
+  // to be called back from the observer and some histograms be incremented.
+  EXPECT_EQ(1U, responses_.size());
+  EXPECT_EQ(responses_.front().type_of_response,
+            AutofillDownloadManagerTest::QUERY_SUCCESSFULL);
+  histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1);
+  histogram.ExpectBucketCount("Autofill.Query.HttpResponseOrErrorCode",
+                              net::HTTP_OK, 1);
+}
+
+TEST_F(AutofillDownloadManagerTest, QueryAPITestWhenTooLongUrl) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      // Enabled
+      // We want to query the API rather than the legacy server.
+      {features::kAutofillUseApi},
+      // Disabled
+      {});
+
+  // Build the form structures that we want to query.
+  FormData form;
+  FormFieldData field;
+  // Fill a really long field that will bust the request URL size limit of 10
+  // KiB. This is not a lot of memory, hence this should not cause problems for
+  // machines running this test. This will force the fallback to POST.
+  field.name_attribute = base::string16(kMaxAPIQueryGetSize, 'a');
+  field.form_control_type = "text";
+  form.fields.push_back(field);
+
+  std::vector<std::unique_ptr<FormStructure>> form_structures;
+  {
+    auto form_structure = std::make_unique<FormStructure>(form);
+    form_structure->set_is_rich_query_enabled(true);
+    form_structures.push_back(std::move(form_structure));
+  }
+
+  AutofillDownloadManager download_manager(&driver_, this, "dummykey");
+
+  // Start the query request and look if it is successful. No response was
+  // received yet.
+  base::HistogramTester histogram;
+  EXPECT_TRUE(
+      download_manager.StartQueryRequest(ToRawPointerVector(form_structures)));
+
+  // Verify request.
+  // Verify if histograms are right.
+  histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
+                               AutofillMetrics::QUERY_SENT, 1);
+  // Verify that the logged method is POST.
+  histogram.ExpectUniqueSample("Autofill.Query.Method", METHOD_POST, 1);
+
+  // Get the latest request that the test URL loader sent.
+  network::TestURLLoaderFactory::PendingRequest* request =
+      test_url_loader_factory_.GetPendingRequest(0);
+  // Verify that the POST URL is used when request data too large.
+  const std::string expected_url = {
+      "https://clients1.google.com/v1/pages:get?alt=proto"};
+  // Verify API key header.
+  EXPECT_EQ(request->request.url, expected_url);
+  {
+    std::string header_value;
+    EXPECT_TRUE(
+        request->request.headers.GetHeader("X-Goog-Api-Key", &header_value));
+    EXPECT_EQ(header_value, "dummykey");
+  }
+  // Verify Content-Type header.
+  {
+    std::string header_value;
+    ASSERT_TRUE(
+        request->request.headers.GetHeader("Content-Type", &header_value));
+    EXPECT_EQ(header_value, "application/x-protobuf");
+  }
+  // Verify binary response header.
+  {
+    std::string header_value;
+    ASSERT_TRUE(request->request.headers.GetHeader(
+        "X-Goog-Encode-Response-If-Executable", &header_value));
+    EXPECT_EQ(header_value, "base64");
+  }
+  // Verify content of the POST body data.
+  {
+    AutofillPageResourceQueryRequest query_request;
+    ASSERT_TRUE(GetAutofillPageResourceQueryRequestFromRequest(request,
+                                                               &query_request));
+    AutofillPageQueryRequest request_content;
+    ASSERT_TRUE(DeserializeAutofillPageQueryRequest(
+        query_request.serialized_request(), &request_content));
+    // Verify form content.
+    ASSERT_EQ(request_content.forms().size(), 1);
+    EXPECT_EQ(request_content.forms(0).signature(),
+              form_structures[0]->form_signature());
+    // Verify field content.
+    ASSERT_EQ(request_content.forms(0).fields().size(), 1);
+    EXPECT_EQ(request_content.forms(0).fields(0).signature(),
+              form_structures[0]->field(0)->GetFieldSignature());
+  }
+
+  // Verify response.
   test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
       request, "dummy response");
   // Upon reception of a suggestions query, we expect OnLoadedServerPredictions
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 665162d..b9107c1 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -99,11 +99,11 @@
 
 // Controls whether the manual fallback will be present.
 const base::Feature kAutofillManualFallback{"AutofillManualFallback",
-                                            base::FEATURE_DISABLED_BY_DEFAULT};
+                                            base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Controls whether the manual fallback will include addresses and cards.
 const base::Feature kAutofillManualFallbackPhaseTwo{
-    "AutofillManualFallbackPhaseTwo", base::FEATURE_DISABLED_BY_DEFAULT};
+    "AutofillManualFallbackPhaseTwo", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kAutofillPruneSuggestions{
     "AutofillPruneSuggestions", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/autofill/core/common/autofill_l10n_util.cc b/components/autofill/core/common/autofill_l10n_util.cc
index f22057ab..d964442 100644
--- a/components/autofill/core/common/autofill_l10n_util.cc
+++ b/components/autofill/core/common/autofill_l10n_util.cc
@@ -16,10 +16,10 @@
 namespace l10n {
 
 std::unique_ptr<icu::Collator> GetCollatorForLocale(const icu::Locale& locale) {
-  UErrorCode ignored = U_ZERO_ERROR;
+  UErrorCode error_code = U_ZERO_ERROR;
   std::unique_ptr<icu::Collator> collator(
-      icu::Collator::createInstance(locale, ignored));
-  if (!collator) {
+      icu::Collator::createInstance(locale, error_code));
+  if (!collator || !U_SUCCESS(error_code)) {
     // On some systems, the default locale is invalid to the eyes of the ICU
     // library. This could be due to a device-specific issue (has been seen in
     // the wild on Android and iOS devices). In the failure case, |collator|
@@ -32,14 +32,15 @@
 
     // Attempt to load the English locale.
     collator.reset(
-        icu::Collator::createInstance(icu::Locale::getEnglish(), ignored));
-    if (!collator) {
+        icu::Collator::createInstance(icu::Locale::getEnglish(), error_code));
+    if (!collator || !U_SUCCESS(error_code)) {
       LOG(ERROR) << "Failed to initialize the ICU Collator with the English "
                  << "locale.";
     }
   }
 
-  UMA_HISTOGRAM_BOOLEAN("Autofill.IcuCollatorCreationSuccess", !!collator);
+  UMA_HISTOGRAM_BOOLEAN("Autofill.IcuCollatorCreationSuccess",
+                        (!!collator && U_SUCCESS(error_code)));
   return collator;
 }
 
diff --git a/components/bookmarks/browser/BUILD.gn b/components/bookmarks/browser/BUILD.gn
index c60cb5f5..0412efc 100644
--- a/components/bookmarks/browser/BUILD.gn
+++ b/components/bookmarks/browser/BUILD.gn
@@ -142,12 +142,15 @@
   ]
 }
 
-fuzzer_test("bookmark_node_data_read_fuzzer") {
-  sources = [
-    "bookmark_node_data_read_fuzzer.cc",
-  ]
-  deps = [
-    ":browser",
-    "//base",
-  ]
+# The fuzzer depends on code that is not built on Mac.
+if (!is_mac) {
+  fuzzer_test("bookmark_node_data_read_fuzzer") {
+    sources = [
+      "bookmark_node_data_read_fuzzer.cc",
+    ]
+    deps = [
+      ":browser",
+      "//base",
+    ]
+  }
 }
diff --git a/components/bookmarks/browser/bookmark_node_data.cc b/components/bookmarks/browser/bookmark_node_data.cc
index d6e9823c..6a5b0e8f5 100644
--- a/components/bookmarks/browser/bookmark_node_data.cc
+++ b/components/bookmarks/browser/bookmark_node_data.cc
@@ -4,18 +4,22 @@
 
 #include "components/bookmarks/browser/bookmark_node_data.h"
 
+#include <algorithm>
 #include <string>
 
+#include "base/numerics/safe_conversions.h"
 #include "base/pickle.h"
-#include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
 #include "components/bookmarks/browser/bookmark_utils.h"
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
 
 namespace bookmarks {
 
 #if !defined(OS_MACOSX)
+namespace {
+constexpr size_t kMaxVectorPreallocateSize = 10000;
+}  // namespace
+
 const char BookmarkNodeData::kClipboardFormatString[] =
     "chromium/x-bookmark-entries";
 #endif
@@ -86,12 +90,22 @@
   }
   children.clear();
   if (!is_url) {
-    uint32_t children_count;
-    if (!iterator->ReadUInt32(&children_count))
+    uint32_t children_count_tmp;
+    if (!iterator->ReadUInt32(&children_count_tmp))
       return false;
-    children.reserve(children_count);
+    if (!base::IsValueInRangeForNumericType<size_t>(children_count_tmp)) {
+      LOG(WARNING) << "children_count failed bounds check";
+      return false;
+    }
+    const size_t children_count =
+        base::checked_cast<size_t>(children_count_tmp);
+    // Restrict vector preallocation to prevent OOM crashes on invalid (or
+    // malicious) pickles.
+    if (children_count > kMaxVectorPreallocateSize)
+      LOG(WARNING) << "children_count exceeds kMaxVectorPreallocateSize";
+    children.reserve(std::min(children_count, kMaxVectorPreallocateSize));
     for (size_t i = 0; i < children_count; ++i) {
-      children.push_back(Element());
+      children.emplace_back();
       if (!children.back().ReadFromPickle(iterator))
         return false;
     }
@@ -242,13 +256,23 @@
 
 bool BookmarkNodeData::ReadFromPickle(base::Pickle* pickle) {
   base::PickleIterator data_iterator(*pickle);
-  uint32_t element_count;
+  uint32_t element_count_tmp;
   if (profile_path_.ReadFromPickle(&data_iterator) &&
-      data_iterator.ReadUInt32(&element_count)) {
+      data_iterator.ReadUInt32(&element_count_tmp)) {
+    if (!base::IsValueInRangeForNumericType<size_t>(element_count_tmp)) {
+      LOG(WARNING) << "element_count failed bounds check";
+      return false;
+    }
+    const size_t element_count = base::checked_cast<size_t>(element_count_tmp);
+    // Restrict vector preallocation to prevent OOM crashes on invalid or
+    // malicious pickles.
+    if (element_count > kMaxVectorPreallocateSize)
+      LOG(WARNING) << "element_count exceeds kMaxVectorPreallocateSize";
     std::vector<Element> tmp_elements;
-    tmp_elements.resize(element_count);
+    tmp_elements.reserve(std::min(element_count, kMaxVectorPreallocateSize));
     for (size_t i = 0; i < element_count; ++i) {
-      if (!tmp_elements[i].ReadFromPickle(&data_iterator)) {
+      tmp_elements.emplace_back();
+      if (!tmp_elements.back().ReadFromPickle(&data_iterator)) {
         return false;
       }
     }
diff --git a/components/bookmarks/browser/bookmark_node_data_read_fuzzer.cc b/components/bookmarks/browser/bookmark_node_data_read_fuzzer.cc
index 6de9be98..df83196 100644
--- a/components/bookmarks/browser/bookmark_node_data_read_fuzzer.cc
+++ b/components/bookmarks/browser/bookmark_node_data_read_fuzzer.cc
@@ -9,7 +9,13 @@
 #include "base/pickle.h"
 #include "components/bookmarks/browser/bookmark_node_data.h"
 
+struct Environment {
+  Environment() { logging::SetMinLogLevel(logging::LOG_FATAL); }
+};
+
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static Environment env;
+
   base::Pickle pickle(reinterpret_cast<const char*>(data), size);
   bookmarks::BookmarkNodeData bookmark_node_data;
   bookmark_node_data.ReadFromPickle(&pickle);
diff --git a/components/bookmarks/browser/bookmark_node_data_unittest.cc b/components/bookmarks/browser/bookmark_node_data_unittest.cc
index 21b593d..b12a447 100644
--- a/components/bookmarks/browser/bookmark_node_data_unittest.cc
+++ b/components/bookmarks/browser/bookmark_node_data_unittest.cc
@@ -414,4 +414,15 @@
   EXPECT_EQ("someothervalue", meta_info_map["someotherkey"]);
 }
 
+#if !defined(OS_MACOSX)
+TEST_F(BookmarkNodeDataTest, ReadFromPickleTooManyNodes) {
+  // Test case determined by a fuzzer. See https://crbug.com/956583.
+  const char pickled_data[] = {0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+                               0x00, 0x00, 0xff, 0x03, 0x03, 0x41};
+  base::Pickle pickle(pickled_data, sizeof(pickled_data));
+  BookmarkNodeData bookmark_node_data;
+  EXPECT_FALSE(bookmark_node_data.ReadFromPickle(&pickle));
+}
+#endif
+
 }  // namespace bookmarks
diff --git a/components/download/internal/common/BUILD.gn b/components/download/internal/common/BUILD.gn
index 2c3ee13..419ee87c 100644
--- a/components/download/internal/common/BUILD.gn
+++ b/components/download/internal/common/BUILD.gn
@@ -74,8 +74,10 @@
     "//components/leveldb_proto",
     "//mojo/public/c/system",
     "//net",
+    "//services/device/public/mojom:mojom",
     "//services/metrics/public/cpp:ukm_builders",
     "//services/network/public/cpp",
+    "//services/service_manager/public/cpp:cpp",
   ]
 
   if (is_android) {
diff --git a/components/download/internal/common/DEPS b/components/download/internal/common/DEPS
index 713aa40..015703b0 100644
--- a/components/download/internal/common/DEPS
+++ b/components/download/internal/common/DEPS
@@ -22,7 +22,9 @@
   "+net/http/http_util.h",
   "+net/traffic_annotation/network_traffic_annotation.h",
   "+net/url_request/url_request_context_getter.h",
+  "+services/device/public/mojom",
   "+services/metrics/public/cpp",
   "+services/network/public/cpp",
   "+services/network/public/mojom",
+  "+services/service_manager/public/cpp",
 ]
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc
index b1bc7b7d..09a3173f 100644
--- a/components/download/internal/common/download_item_impl.cc
+++ b/components/download/internal/common/download_item_impl.cc
@@ -421,7 +421,7 @@
       weak_ptr_factory_(this) {
   job_ = DownloadJobFactory::CreateJob(this, std::move(request_handle),
                                        DownloadCreateInfo(), true, nullptr,
-                                       nullptr);
+                                       nullptr, nullptr);
   delegate_->Attach();
   Init(true /* actively downloading */, TYPE_SAVE_PAGE_AS);
 }
@@ -1398,7 +1398,8 @@
   download_file_ = std::move(file);
   job_ = DownloadJobFactory::CreateJob(
       this, std::move(req_handle), new_create_info, false,
-      std::move(url_loader_factory_getter), url_request_context_getter);
+      std::move(url_loader_factory_getter), url_request_context_getter,
+      delegate_ ? delegate_->GetServiceManagerConnector() : nullptr);
   if (job_->IsParallelizable()) {
     RecordParallelizableDownloadCount(START_COUNT, IsParallelDownloadEnabled());
   }
diff --git a/components/download/internal/common/download_item_impl_delegate.cc b/components/download/internal/common/download_item_impl_delegate.cc
index cc3fb6af5d..f5dff20a 100644
--- a/components/download/internal/common/download_item_impl_delegate.cc
+++ b/components/download/internal/common/download_item_impl_delegate.cc
@@ -103,4 +103,9 @@
 
 void DownloadItemImplDelegate::ReportBytesWasted(DownloadItemImpl* download) {}
 
+service_manager::Connector*
+DownloadItemImplDelegate::GetServiceManagerConnector() {
+  return nullptr;
+}
+
 }  // namespace download
diff --git a/components/download/internal/common/download_job_factory.cc b/components/download/internal/common/download_job_factory.cc
index f3cea3ae..0c35188 100644
--- a/components/download/internal/common/download_job_factory.cc
+++ b/components/download/internal/common/download_job_factory.cc
@@ -98,7 +98,8 @@
     bool is_save_package_download,
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
-    net::URLRequestContextGetter* url_request_context_getter) {
+    net::URLRequestContextGetter* url_request_context_getter,
+    service_manager::Connector* connector) {
   if (is_save_package_download) {
     return std::make_unique<SavePackageDownloadJob>(download_item,
                                                     std::move(req_handle));
@@ -109,7 +110,8 @@
   if (IsParallelDownloadEnabled() && is_parallelizable) {
     return std::make_unique<ParallelDownloadJob>(
         download_item, std::move(req_handle), create_info,
-        std::move(url_loader_factory_getter), url_request_context_getter);
+        std::move(url_loader_factory_getter), url_request_context_getter,
+        connector);
   }
 
   // An ordinary download job.
diff --git a/components/download/internal/common/download_worker.cc b/components/download/internal/common/download_worker.cc
index 05f8261..ad5bec8 100644
--- a/components/download/internal/common/download_worker.cc
+++ b/components/download/internal/common/download_worker.cc
@@ -16,6 +16,7 @@
 #include "net/url_request/url_request_context_getter.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/service_manager/public/cpp/connector.h"
 
 namespace download {
 namespace {
@@ -55,10 +56,12 @@
         url_loader_factory_getter,
     const URLSecurityPolicy& url_security_policy,
     scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   auto downloader = UrlDownloadHandlerFactory::Create(
       std::move(params), delegate, std::move(url_loader_factory_getter),
-      url_security_policy, std::move(url_request_context_getter), task_runner);
+      url_security_policy, std::move(url_request_context_getter),
+      std::move(connector), task_runner);
   task_runner->PostTask(
       FROM_HERE,
       base::BindOnce(&UrlDownloadHandler::Delegate::OnUrlDownloadHandlerCreated,
@@ -87,13 +90,15 @@
     std::unique_ptr<DownloadUrlParameters> params,
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
-    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
+    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+    service_manager::Connector* connector) {
   GetIOTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&CreateUrlDownloadHandler, std::move(params),
                                 weak_factory_.GetWeakPtr(),
                                 std::move(url_loader_factory_getter),
                                 base::BindRepeating(&IsURLSafe),
                                 std::move(url_request_context_getter),
+                                connector ? connector->Clone() : nullptr,
                                 base::ThreadTaskRunnerHandle::Get()));
 }
 
diff --git a/components/download/internal/common/download_worker.h b/components/download/internal/common/download_worker.h
index ec81471..6021c06 100644
--- a/components/download/internal/common/download_worker.h
+++ b/components/download/internal/common/download_worker.h
@@ -17,7 +17,11 @@
 
 namespace net {
 class URLRequestContextGetter;
-}
+}  // namespace net
+
+namespace service_manager {
+class Connector;
+}  // namespace service_manager
 
 namespace download {
 class DownloadURLLoaderFactoryGetter;
@@ -53,7 +57,8 @@
       std::unique_ptr<DownloadUrlParameters> params,
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
-      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
+      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+      service_manager::Connector* connector);
 
   // Download operations.
   void Pause();
diff --git a/components/download/internal/common/in_progress_download_manager.cc b/components/download/internal/common/in_progress_download_manager.cc
index 3298338e..f488722 100644
--- a/components/download/internal/common/in_progress_download_manager.cc
+++ b/components/download/internal/common/in_progress_download_manager.cc
@@ -27,6 +27,7 @@
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/resource_response.h"
+#include "services/service_manager/public/cpp/connector.h"
 
 #if defined(OS_ANDROID)
 #include "components/download/internal/common/android/download_collection_bridge.h"
@@ -86,13 +87,15 @@
     const GURL& site_url,
     const GURL& tab_url,
     const GURL& tab_referrer_url,
+    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) {
   DCHECK(GetIOTaskRunner()->BelongsToCurrentThread());
   UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader(
       ResourceDownloader::BeginDownload(
           download_manager, std::move(params), std::move(request),
           std::move(url_loader_factory_getter), url_security_policy, site_url,
-          tab_url, tab_referrer_url, is_new_download, false, main_task_runner)
+          tab_url, tab_referrer_url, is_new_download, false,
+          std::move(connector), main_task_runner)
           .release(),
       base::OnTaskRunnerDeleter(base::ThreadTaskRunnerHandle::Get()));
 
@@ -114,6 +117,7 @@
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter,
     const URLSecurityPolicy& url_security_policy,
+    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) {
   DCHECK(GetIOTaskRunner()->BelongsToCurrentThread());
   UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader(
@@ -123,7 +127,7 @@
           std::move(url_chain), std::move(response), std::move(cert_status),
           std::move(url_loader_client_endpoints),
           std::move(url_loader_factory_getter), url_security_policy,
-          main_task_runner)
+          std::move(connector), main_task_runner)
           .release(),
       base::OnTaskRunnerDeleter(base::ThreadTaskRunnerHandle::Get()));
 
@@ -204,7 +208,6 @@
 
 bool InProgressDownloadManager::DownloadUrl(
     std::unique_ptr<DownloadUrlParameters> params) {
-  DCHECK(!delegate_);
   DCHECK(params->is_transient());
 
   if (!url_loader_factory_getter_)
@@ -248,13 +251,15 @@
     const GURL& tab_referrer_url) {
   std::unique_ptr<network::ResourceRequest> request =
       CreateResourceRequest(params.get());
+  auto connector = delegate_ ? delegate_->GetServiceConnector() : nullptr;
   GetIOTaskRunner()->PostTask(
       FROM_HERE,
       base::BindOnce(&BeginResourceDownload, std::move(params),
                      std::move(request), std::move(url_loader_factory_getter),
                      url_security_policy_, is_new_download,
                      weak_factory_.GetWeakPtr(), site_url, tab_url,
-                     tab_referrer_url, base::ThreadTaskRunnerHandle::Get()));
+                     tab_referrer_url, std::move(connector),
+                     base::ThreadTaskRunnerHandle::Get()));
 }
 
 void InProgressDownloadManager::InterceptDownloadFromNavigation(
@@ -269,16 +274,17 @@
     net::CertStatus cert_status,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter) {
+  auto connector = delegate_ ? delegate_->GetServiceConnector() : nullptr;
   GetIOTaskRunner()->PostTask(
       FROM_HERE,
-      base::BindOnce(&CreateDownloadHandlerForNavigation,
-                     weak_factory_.GetWeakPtr(), std::move(resource_request),
-                     render_process_id, render_frame_id, site_url, tab_url,
-                     tab_referrer_url, std::move(url_chain),
-                     std::move(response), std::move(cert_status),
-                     std::move(url_loader_client_endpoints),
-                     std::move(url_loader_factory_getter), url_security_policy_,
-                     base::ThreadTaskRunnerHandle::Get()));
+      base::BindOnce(
+          &CreateDownloadHandlerForNavigation, weak_factory_.GetWeakPtr(),
+          std::move(resource_request), render_process_id, render_frame_id,
+          site_url, tab_url, tab_referrer_url, std::move(url_chain),
+          std::move(response), std::move(cert_status),
+          std::move(url_loader_client_endpoints),
+          std::move(url_loader_factory_getter), url_security_policy_,
+          std::move(connector), base::ThreadTaskRunnerHandle::Get()));
 }
 
 void InProgressDownloadManager::Initialize(
@@ -382,7 +388,9 @@
                                       info->mime_type, is_origin_secure_cb_);
   }
 
-  if (delegate_) {
+  // If the download cannot be found locally, ask |delegate_| to provide the
+  // DownloadItem.
+  if (delegate_ && !GetDownloadByGuid(info->guid)) {
     delegate_->StartDownloadItem(
         std::move(info), on_started,
         base::BindOnce(&InProgressDownloadManager::StartDownloadWithItem,
diff --git a/components/download/internal/common/parallel_download_job.cc b/components/download/internal/common/parallel_download_job.cc
index 376700af3..1ac7dbbb 100644
--- a/components/download/internal/common/parallel_download_job.cc
+++ b/components/download/internal/common/parallel_download_job.cc
@@ -27,7 +27,8 @@
     const DownloadCreateInfo& create_info,
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
-    net::URLRequestContextGetter* url_request_context_getter)
+    net::URLRequestContextGetter* url_request_context_getter,
+    service_manager::Connector* connector)
     : DownloadJobImpl(download_item, std::move(request_handle), true),
       initial_request_offset_(create_info.offset),
       initial_received_slices_(download_item->GetReceivedSlices()),
@@ -35,7 +36,8 @@
       requests_sent_(false),
       is_canceled_(false),
       url_loader_factory_getter_(std::move(url_loader_factory_getter)),
-      url_request_context_getter_(url_request_context_getter) {}
+      url_request_context_getter_(url_request_context_getter),
+      connector_(connector) {}
 
 ParallelDownloadJob::~ParallelDownloadJob() = default;
 
@@ -298,7 +300,7 @@
 
   // Send the request.
   worker->SendRequest(std::move(download_params), url_loader_factory_getter_,
-                      url_request_context_getter_);
+                      url_request_context_getter_, connector_);
   DCHECK(workers_.find(offset) == workers_.end());
   workers_[offset] = std::move(worker);
 }
diff --git a/components/download/internal/common/parallel_download_job.h b/components/download/internal/common/parallel_download_job.h
index 1c79129..71c45c86 100644
--- a/components/download/internal/common/parallel_download_job.h
+++ b/components/download/internal/common/parallel_download_job.h
@@ -19,7 +19,11 @@
 
 namespace net {
 class URLRequestContextGetter;
-}
+}  // namespace net
+
+namespace service_manager {
+class Connector;
+}  // namespace service_manager
 
 namespace download {
 
@@ -38,7 +42,8 @@
       const DownloadCreateInfo& create_info,
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
-      net::URLRequestContextGetter* url_request_context_getter);
+      net::URLRequestContextGetter* url_request_context_getter,
+      service_manager::Connector* connector);
   ~ParallelDownloadJob() override;
 
   // DownloadJobImpl implementation.
@@ -122,6 +127,9 @@
   // is disabled.
   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
 
+  // Connector used for establishing the connection to the ServiceManager.
+  service_manager::Connector* connector_;
+
   DISALLOW_COPY_AND_ASSIGN(ParallelDownloadJob);
 };
 
diff --git a/components/download/internal/common/parallel_download_job_unittest.cc b/components/download/internal/common/parallel_download_job_unittest.cc
index 7e66b75..d227cf42 100644
--- a/components/download/internal/common/parallel_download_job_unittest.cc
+++ b/components/download/internal/common/parallel_download_job_unittest.cc
@@ -69,6 +69,7 @@
                             std::move(request_handle),
                             create_info,
                             nullptr,
+                            nullptr,
                             nullptr),
         request_count_(request_count),
         min_slice_size_(min_slice_size),
diff --git a/components/download/internal/common/resource_downloader.cc b/components/download/internal/common/resource_downloader.cc
index b5b86b0..9d8d4fd 100644
--- a/components/download/internal/common/resource_downloader.cc
+++ b/components/download/internal/common/resource_downloader.cc
@@ -10,7 +10,10 @@
 #include "components/download/public/common/download_url_loader_factory_getter.h"
 #include "components/download/public/common/stream_handle_input_stream.h"
 #include "components/download/public/common/url_download_request_handle.h"
+#include "services/device/public/mojom/constants.mojom.h"
+#include "services/device/public/mojom/wake_lock_provider.mojom.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/service_manager/public/cpp/connector.h"
 
 namespace network {
 struct ResourceResponseHead;
@@ -67,12 +70,14 @@
     const GURL& tab_referrer_url,
     bool is_new_download,
     bool is_parallel_request,
+    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   auto downloader = std::make_unique<ResourceDownloader>(
       delegate, std::move(request), params->render_process_host_id(),
       params->render_frame_host_routing_id(), site_url, tab_url,
       tab_referrer_url, is_new_download, task_runner,
-      std::move(url_loader_factory_getter), url_security_policy);
+      std::move(url_loader_factory_getter), url_security_policy,
+      std::move(connector));
 
   downloader->Start(std::move(params), is_parallel_request);
   return downloader;
@@ -95,11 +100,13 @@
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
     const URLSecurityPolicy& url_security_policy,
+    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   auto downloader = std::make_unique<ResourceDownloader>(
       delegate, std::move(resource_request), render_process_id, render_frame_id,
       site_url, tab_url, tab_referrer_url, true, task_runner,
-      std::move(url_loader_factory_getter), url_security_policy);
+      std::move(url_loader_factory_getter), url_security_policy,
+      std::move(connector));
   downloader->InterceptResponse(std::move(response), std::move(url_chain),
                                 cert_status,
                                 std::move(url_loader_client_endpoints));
@@ -118,7 +125,8 @@
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
-    const URLSecurityPolicy& url_security_policy)
+    const URLSecurityPolicy& url_security_policy,
+    std::unique_ptr<service_manager::Connector> connector)
     : delegate_(delegate),
       resource_request_(std::move(resource_request)),
       is_new_download_(is_new_download),
@@ -130,7 +138,9 @@
       delegate_task_runner_(task_runner),
       url_loader_factory_getter_(std::move(url_loader_factory_getter)),
       url_security_policy_(url_security_policy),
-      weak_ptr_factory_(this) {}
+      weak_ptr_factory_(this) {
+  RequestWakeLock(connector.get());
+}
 
 ResourceDownloader::~ResourceDownloader() = default;
 
@@ -254,10 +264,27 @@
 }
 
 void ResourceDownloader::Destroy() {
+  if (wake_lock_)
+    wake_lock_->CancelWakeLock();
   delegate_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&UrlDownloadHandler::Delegate::OnUrlDownloadStopped,
                      delegate_, this));
 }
 
+void ResourceDownloader::RequestWakeLock(
+    service_manager::Connector* connector) {
+  if (!connector)
+    return;
+  device::mojom::WakeLockProviderPtr wake_lock_provider;
+  connector->BindInterface(device::mojom::kServiceName,
+                           mojo::MakeRequest(&wake_lock_provider));
+  wake_lock_provider->GetWakeLockWithoutContext(
+      device::mojom::WakeLockType::kPreventAppSuspension,
+      device::mojom::WakeLockReason::kOther, "Download in progress",
+      mojo::MakeRequest(&wake_lock_));
+
+  wake_lock_->RequestWakeLock();
+}
+
 }  // namespace download
diff --git a/components/download/internal/common/resource_downloader.h b/components/download/internal/common/resource_downloader.h
index 63664cf..b2f8ec7 100644
--- a/components/download/internal/common/resource_downloader.h
+++ b/components/download/internal/common/resource_downloader.h
@@ -12,9 +12,14 @@
 #include "components/download/public/common/url_download_handler.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "net/cert/cert_status_flags.h"
+#include "services/device/public/mojom/wake_lock.mojom.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
+namespace service_manager {
+class Connector;
+}  // namespace service_manager
+
 namespace download {
 class DownloadURLLoaderFactoryGetter;
 
@@ -36,6 +41,7 @@
       const GURL& tab_referrer_url,
       bool is_new_download,
       bool is_parallel_request,
+      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
 
   // Create a ResourceDownloader from a navigation that turns to be a download.
@@ -56,6 +62,7 @@
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
       const URLSecurityPolicy& url_security_policy,
+      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
 
   ResourceDownloader(
@@ -70,7 +77,8 @@
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
-      const URLSecurityPolicy& url_security_policy);
+      const URLSecurityPolicy& url_security_policy,
+      std::unique_ptr<service_manager::Connector> connector);
   ~ResourceDownloader() override;
 
   // download::DownloadResponseHandler::Delegate
@@ -101,6 +109,9 @@
   // Ask the |delegate_| to destroy this object.
   void Destroy();
 
+  // Requests the wake lock using |connector|.
+  void RequestWakeLock(service_manager::Connector* connector);
+
   base::WeakPtr<download::UrlDownloadHandler::Delegate> delegate_;
 
   // The ResourceRequest for this object.
@@ -154,6 +165,11 @@
   // Used to check if the URL is safe to request.
   URLSecurityPolicy url_security_policy_;
 
+  // Used to keep the system from sleeping while a download is ongoing. If the
+  // system enters power saving mode while a download is alive, it can cause
+  // download to be interrupted.
+  device::mojom::WakeLockPtr wake_lock_;
+
   base::WeakPtrFactory<ResourceDownloader> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ResourceDownloader);
diff --git a/components/download/internal/common/url_download_handler_factory.cc b/components/download/internal/common/url_download_handler_factory.cc
index b88c1ff..c295bc9 100644
--- a/components/download/internal/common/url_download_handler_factory.cc
+++ b/components/download/internal/common/url_download_handler_factory.cc
@@ -12,6 +12,7 @@
 #include "components/download/public/common/download_utils.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/service_manager/public/cpp/connector.h"
 
 namespace download {
 
@@ -31,6 +32,7 @@
           url_loader_factory_getter,
       const URLSecurityPolicy& url_security_policy,
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) override {
     std::unique_ptr<network::ResourceRequest> request =
         CreateResourceRequest(params.get());
@@ -38,7 +40,7 @@
         download::ResourceDownloader::BeginDownload(
             delegate, std::move(params), std::move(request),
             std::move(url_loader_factory_getter), url_security_policy, GURL(),
-            GURL(), GURL(), true, true, task_runner)
+            GURL(), GURL(), true, true, std::move(connector), task_runner)
             .release(),
         base::OnTaskRunnerDeleter(base::ThreadTaskRunnerHandle::Get()));
   }
@@ -66,6 +68,7 @@
         url_loader_factory_getter,
     const URLSecurityPolicy& url_security_policy,
     scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   base::AutoLock auto_lock(GetURLDownloadHandlerFactoryLock());
   if (!g_url_download_handler_factory)
@@ -73,7 +76,7 @@
   return g_url_download_handler_factory->CreateUrlDownloadHandler(
       std::move(params), delegate, std::move(url_loader_factory_getter),
       std::move(url_security_policy), std::move(url_request_context_getter),
-      task_runner);
+      std::move(connector), task_runner);
 }
 
 // static
diff --git a/components/download/public/common/download_item_impl_delegate.h b/components/download/public/common/download_item_impl_delegate.h
index a6eb5429..e67be44 100644
--- a/components/download/public/common/download_item_impl_delegate.h
+++ b/components/download/public/common/download_item_impl_delegate.h
@@ -15,6 +15,10 @@
 #include "components/download/public/common/download_item.h"
 #include "components/download/public/common/download_url_parameters.h"
 
+namespace service_manager {
+class Connector;
+}  // namespace service_manager
+
 namespace download {
 struct DownloadEntry;
 class DownloadItemImpl;
@@ -113,6 +117,9 @@
   // Report extra bytes wasted during resumption.
   virtual void ReportBytesWasted(DownloadItemImpl* download);
 
+  // Gets the ServiceManager connector that can be used on UI thread.
+  virtual service_manager::Connector* GetServiceManagerConnector();
+
  private:
   // For "Outlives attached DownloadItemImpl" invariant assertion.
   int count_;
diff --git a/components/download/public/common/download_job_factory.h b/components/download/public/common/download_job_factory.h
index cd44f441..d6660c107 100644
--- a/components/download/public/common/download_job_factory.h
+++ b/components/download/public/common/download_job_factory.h
@@ -13,7 +13,11 @@
 
 namespace net {
 class URLRequestContextGetter;
-}
+}  // namespace net
+
+namespace service_manager {
+class Connector;
+}  // namespace service_manager
 
 namespace download {
 
@@ -32,7 +36,8 @@
       bool is_save_package_download,
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
-      net::URLRequestContextGetter* url_request_context_getter);
+      net::URLRequestContextGetter* url_request_context_getter,
+      service_manager::Connector* connector);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DownloadJobFactory);
diff --git a/components/download/public/common/in_progress_download_manager.h b/components/download/public/common/in_progress_download_manager.h
index cebda480..feb59cd 100644
--- a/components/download/public/common/in_progress_download_manager.h
+++ b/components/download/public/common/in_progress_download_manager.h
@@ -24,11 +24,15 @@
 
 namespace net {
 class URLRequestContextGetter;
-}
+}  // namespace net
 
 namespace network {
 struct ResourceResponse;
-}
+}  // namespace network
+
+namespace service_manager {
+class Connector;
+}  // namespace service_manager
 
 namespace download {
 
@@ -77,6 +81,9 @@
     // TODO(qinmin): remove this once network service is fully enabled.
     virtual net::URLRequestContextGetter* GetURLRequestContextGetter(
         const DownloadCreateInfo& download_create_info);
+
+    virtual std::unique_ptr<service_manager::Connector>
+    GetServiceConnector() = 0;
   };
 
   using IsOriginSecureCallback = base::RepeatingCallback<bool(const GURL&)>;
diff --git a/components/download/public/common/url_download_handler_factory.h b/components/download/public/common/url_download_handler_factory.h
index bbe7195..8b30691e 100644
--- a/components/download/public/common/url_download_handler_factory.h
+++ b/components/download/public/common/url_download_handler_factory.h
@@ -11,7 +11,11 @@
 
 namespace net {
 class URLRequestContextGetter;
-}
+}  // namespace net
+
+namespace service_manager {
+class Connector;
+}  // namespace service_manager
 
 namespace download {
 class DownloadURLLoaderFactoryGetter;
@@ -35,6 +39,7 @@
           url_loader_factory_getter,
       const URLSecurityPolicy& url_security_policy,
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
 
   virtual ~UrlDownloadHandlerFactory();
@@ -52,6 +57,7 @@
           url_loader_factory_getter,
       const URLSecurityPolicy& url_security_policy,
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) = 0;
 };
 
diff --git a/components/gcm_driver/crypto/gcm_encryption_provider.cc b/components/gcm_driver/crypto/gcm_encryption_provider.cc
index bf08a34..aa8ac17 100644
--- a/components/gcm_driver/crypto/gcm_encryption_provider.cc
+++ b/components/gcm_driver/crypto/gcm_encryption_provider.cc
@@ -95,9 +95,9 @@
 void GCMEncryptionProvider::RemoveEncryptionInfo(
     const std::string& app_id,
     const std::string& authorized_entity,
-    const base::Closure& callback) {
+    base::OnceClosure callback) {
   DCHECK(key_store_);
-  key_store_->RemoveKeys(app_id, authorized_entity, callback);
+  key_store_->RemoveKeys(app_id, authorized_entity, std::move(callback));
 }
 
 bool GCMEncryptionProvider::IsEncryptedMessage(const IncomingMessage& message)
diff --git a/components/gcm_driver/crypto/gcm_encryption_provider.h b/components/gcm_driver/crypto/gcm_encryption_provider.h
index 812584a9..74f8e46b 100644
--- a/components/gcm_driver/crypto/gcm_encryption_provider.h
+++ b/components/gcm_driver/crypto/gcm_encryption_provider.h
@@ -70,7 +70,7 @@
   // all InstanceID tokens, or "" for non-InstanceID GCM registrations.
   void RemoveEncryptionInfo(const std::string& app_id,
                             const std::string& authorized_entity,
-                            const base::Closure& callback);
+                            base::OnceClosure callback);
 
   // Determines whether |message| contains encrypted content.
   bool IsEncryptedMessage(const IncomingMessage& message) const;
diff --git a/components/gcm_driver/fake_gcm_profile_service.cc b/components/gcm_driver/fake_gcm_profile_service.cc
index 2a5de23..1a3992f0 100644
--- a/components/gcm_driver/fake_gcm_profile_service.cc
+++ b/components/gcm_driver/fake_gcm_profile_service.cc
@@ -54,11 +54,11 @@
                 const std::string& authorized_entity,
                 const std::string& scope,
                 const std::map<std::string, std::string>& options,
-                const GetTokenCallback& callback) override;
+                GetTokenCallback callback) override;
   void DeleteToken(const std::string& app_id,
                    const std::string& authorized_entity,
                    const std::string& scope,
-                   const DeleteTokenCallback& callback) override;
+                   DeleteTokenCallback callback) override;
 
  private:
   void DoRegister(const std::string& app_id,
@@ -168,24 +168,24 @@
     const std::string& authorized_entity,
     const std::string& scope,
     const std::map<std::string, std::string>& options,
-    const GetTokenCallback& callback) {
+    GetTokenCallback callback) {
   if (service_->is_offline_)
     return;  // Drop request.
 
-  instance_id::FakeGCMDriverForInstanceID::GetToken(app_id, authorized_entity,
-                                                    scope, options, callback);
+  instance_id::FakeGCMDriverForInstanceID::GetToken(
+      app_id, authorized_entity, scope, options, std::move(callback));
 }
 
 void FakeGCMProfileService::CustomFakeGCMDriver::DeleteToken(
     const std::string& app_id,
     const std::string& authorized_entity,
     const std::string& scope,
-    const DeleteTokenCallback& callback) {
+    DeleteTokenCallback callback) {
   if (service_->is_offline_)
     return;  // Drop request.
 
   instance_id::FakeGCMDriverForInstanceID::DeleteToken(
-      app_id, authorized_entity, scope, callback);
+      app_id, authorized_entity, scope, std::move(callback));
 }
 
 void FakeGCMProfileService::CustomFakeGCMDriver::OnDispatchMessage(
diff --git a/components/gcm_driver/gcm_delayed_task_controller.cc b/components/gcm_driver/gcm_delayed_task_controller.cc
index b5cc99da..7396330 100644
--- a/components/gcm_driver/gcm_delayed_task_controller.cc
+++ b/components/gcm_driver/gcm_delayed_task_controller.cc
@@ -13,11 +13,10 @@
 GCMDelayedTaskController::GCMDelayedTaskController() : ready_(false) {
 }
 
-GCMDelayedTaskController::~GCMDelayedTaskController() {
-}
+GCMDelayedTaskController::~GCMDelayedTaskController() = default;
 
-void GCMDelayedTaskController::AddTask(const base::Closure& task) {
-  delayed_tasks_.push_back(task);
+void GCMDelayedTaskController::AddTask(base::OnceClosure task) {
+  delayed_tasks_.push_back(std::move(task));
 }
 
 void GCMDelayedTaskController::SetReady() {
@@ -33,7 +32,7 @@
   DCHECK(ready_);
 
   for (size_t i = 0; i < delayed_tasks_.size(); ++i)
-    delayed_tasks_[i].Run();
+    std::move(delayed_tasks_[i]).Run();
   delayed_tasks_.clear();
 }
 
diff --git a/components/gcm_driver/gcm_delayed_task_controller.h b/components/gcm_driver/gcm_delayed_task_controller.h
index 0a87ee3..bdd500fe 100644
--- a/components/gcm_driver/gcm_delayed_task_controller.h
+++ b/components/gcm_driver/gcm_delayed_task_controller.h
@@ -19,7 +19,7 @@
   ~GCMDelayedTaskController();
 
   // Adds a task that will be invoked once we're ready.
-  void AddTask(const base::Closure& task);
+  void AddTask(base::OnceClosure task);
 
   // Sets ready status, which will release all of the pending tasks.
   void SetReady();
@@ -33,7 +33,7 @@
   // Flag that indicates that controlled component is ready.
   bool ready_;
 
-  std::vector<base::Closure> delayed_tasks_;
+  std::vector<base::OnceClosure> delayed_tasks_;
 
   DISALLOW_COPY_AND_ASSIGN(GCMDelayedTaskController);
 };
diff --git a/components/gcm_driver/gcm_driver.cc b/components/gcm_driver/gcm_driver.cc
index 8345ce3d..d833a27 100644
--- a/components/gcm_driver/gcm_driver.cc
+++ b/components/gcm_driver/gcm_driver.cc
@@ -23,9 +23,9 @@
 InstanceIDHandler::~InstanceIDHandler() {
 }
 
-void InstanceIDHandler::DeleteAllTokensForApp(
-    const std::string& app_id, const DeleteTokenCallback& callback) {
-  DeleteToken(app_id, "*", "*", callback);
+void InstanceIDHandler::DeleteAllTokensForApp(const std::string& app_id,
+                                              DeleteTokenCallback callback) {
+  DeleteToken(app_id, "*", "*", std::move(callback));
 }
 
 GCMDriver::GCMDriver(
@@ -43,20 +43,20 @@
 
 void GCMDriver::Register(const std::string& app_id,
                          const std::vector<std::string>& sender_ids,
-                         const RegisterCallback& callback) {
+                         RegisterCallback callback) {
   DCHECK(!app_id.empty());
   DCHECK(!sender_ids.empty() && sender_ids.size() <= kMaxSenders);
   DCHECK(!callback.is_null());
 
   GCMClient::Result result = EnsureStarted(GCMClient::IMMEDIATE_START);
   if (result != GCMClient::SUCCESS) {
-    callback.Run(std::string(), result);
+    std::move(callback).Run(std::string(), result);
     return;
   }
 
   // If previous register operation is still in progress, bail out.
   if (register_callbacks_.find(app_id) != register_callbacks_.end()) {
-    callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
+    std::move(callback).Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
     return;
   }
 
@@ -64,7 +64,7 @@
   std::vector<std::string> normalized_sender_ids = sender_ids;
   std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
 
-  register_callbacks_[app_id] = callback;
+  register_callbacks_[app_id] = std::move(callback);
 
   // If previous unregister operation is still in progress, wait until it
   // finishes. We don't want to throw ASYNC_OPERATION_PENDING when the user
@@ -78,12 +78,9 @@
     // Note that some parameters to RegisterAfterUnregister are specified here
     // when the callback is created (base::Bind supports the partial binding
     // of parameters).
-    unregister_iter->second = base::Bind(
-        &GCMDriver::RegisterAfterUnregister,
-        weak_ptr_factory_.GetWeakPtr(),
-        app_id,
-        normalized_sender_ids,
-        unregister_iter->second);
+    unregister_iter->second = base::BindOnce(
+        &GCMDriver::RegisterAfterUnregister, weak_ptr_factory_.GetWeakPtr(),
+        app_id, normalized_sender_ids, std::move(unregister_iter->second));
     return;
   }
 
@@ -91,38 +88,37 @@
 }
 
 void GCMDriver::Unregister(const std::string& app_id,
-                           const UnregisterCallback& callback) {
-  UnregisterInternal(app_id, nullptr /* sender_id */, callback);
+                           UnregisterCallback callback) {
+  UnregisterInternal(app_id, nullptr /* sender_id */, std::move(callback));
 }
 
-void GCMDriver::UnregisterWithSenderId(
-    const std::string& app_id,
-    const std::string& sender_id,
-    const UnregisterCallback& callback) {
+void GCMDriver::UnregisterWithSenderId(const std::string& app_id,
+                                       const std::string& sender_id,
+                                       UnregisterCallback callback) {
   DCHECK(!sender_id.empty());
-  UnregisterInternal(app_id, &sender_id, callback);
+  UnregisterInternal(app_id, &sender_id, std::move(callback));
 }
 
 void GCMDriver::UnregisterInternal(const std::string& app_id,
                                    const std::string* sender_id,
-                                   const UnregisterCallback& callback) {
+                                   UnregisterCallback callback) {
   DCHECK(!app_id.empty());
   DCHECK(!callback.is_null());
 
   GCMClient::Result result = EnsureStarted(GCMClient::IMMEDIATE_START);
   if (result != GCMClient::SUCCESS) {
-    callback.Run(result);
+    std::move(callback).Run(result);
     return;
   }
 
   // If previous un/register operation is still in progress, bail out.
   if (register_callbacks_.find(app_id) != register_callbacks_.end() ||
       unregister_callbacks_.find(app_id) != unregister_callbacks_.end()) {
-    callback.Run(GCMClient::ASYNC_OPERATION_PENDING);
+    std::move(callback).Run(GCMClient::ASYNC_OPERATION_PENDING);
     return;
   }
 
-  unregister_callbacks_[app_id] = callback;
+  unregister_callbacks_[app_id] = std::move(callback);
 
   if (sender_id)
     UnregisterWithSenderIdImpl(app_id, *sender_id);
@@ -177,9 +173,9 @@
     return;
   }
 
-  RegisterCallback callback = callback_iter->second;
+  RegisterCallback callback = std::move(callback_iter->second);
   register_callbacks_.erase(callback_iter);
-  callback.Run(registration_id, result);
+  std::move(callback).Run(registration_id, result);
 }
 
 void GCMDriver::RemoveEncryptionInfoAfterUnregister(const std::string& app_id,
@@ -196,9 +192,9 @@
   if (callback_iter == unregister_callbacks_.end())
     return;
 
-  UnregisterCallback callback = callback_iter->second;
+  UnregisterCallback callback = std::move(callback_iter->second);
   unregister_callbacks_.erase(callback_iter);
-  callback.Run(result);
+  std::move(callback).Run(result);
 }
 
 void GCMDriver::SendFinished(const std::string& app_id,
@@ -315,10 +311,10 @@
 void GCMDriver::RegisterAfterUnregister(
     const std::string& app_id,
     const std::vector<std::string>& normalized_sender_ids,
-    const UnregisterCallback& unregister_callback,
+    UnregisterCallback unregister_callback,
     GCMClient::Result result) {
   // Invoke the original unregister callback.
-  unregister_callback.Run(result);
+  std::move(unregister_callback).Run(result);
 
   // Trigger the pending registration.
   DCHECK(register_callbacks_.find(app_id) != register_callbacks_.end());
diff --git a/components/gcm_driver/gcm_driver.h b/components/gcm_driver/gcm_driver.h
index 0bdb150..d9ecf3d 100644
--- a/components/gcm_driver/gcm_driver.h
+++ b/components/gcm_driver/gcm_driver.h
@@ -33,10 +33,11 @@
 // Provides the InstanceID support via GCMDriver.
 class InstanceIDHandler {
  public:
-  using GetTokenCallback =
-      base::Callback<void(const std::string& token, GCMClient::Result result)>;
+  using GetTokenCallback = base::OnceCallback<void(const std::string& token,
+                                                   GCMClient::Result result)>;
   using ValidateTokenCallback = base::Callback<void(bool is_valid)>;
-  using DeleteTokenCallback = base::Callback<void(GCMClient::Result result)>;
+  using DeleteTokenCallback =
+      base::OnceCallback<void(GCMClient::Result result)>;
   using GetInstanceIDDataCallback =
       base::Callback<void(const std::string& instance_id,
                           const std::string& extra_data)>;
@@ -49,7 +50,7 @@
                         const std::string& authorized_entity,
                         const std::string& scope,
                         const std::map<std::string, std::string>& options,
-                        const GetTokenCallback& callback) = 0;
+                        GetTokenCallback callback) = 0;
   virtual void ValidateToken(const std::string& app_id,
                              const std::string& authorized_entity,
                              const std::string& scope,
@@ -58,9 +59,9 @@
   virtual void DeleteToken(const std::string& app_id,
                            const std::string& authorized_entity,
                            const std::string& scope,
-                           const DeleteTokenCallback& callback) = 0;
+                           DeleteTokenCallback callback) = 0;
   void DeleteAllTokensForApp(const std::string& app_id,
-                             const DeleteTokenCallback& callback);
+                             DeleteTokenCallback callback);
 
   // Persistence support.
   virtual void AddInstanceIDData(const std::string& app_id,
@@ -83,10 +84,10 @@
 
   using GCMAppHandlerMap = std::map<std::string, GCMAppHandler*>;
   using RegisterCallback =
-      base::Callback<void(const std::string& registration_id,
-                          GCMClient::Result result)>;
+      base::OnceCallback<void(const std::string& registration_id,
+                              GCMClient::Result result)>;
   using ValidateRegistrationCallback = base::Callback<void(bool is_valid)>;
-  using UnregisterCallback = base::Callback<void(GCMClient::Result result)>;
+  using UnregisterCallback = base::OnceCallback<void(GCMClient::Result result)>;
   using SendCallback = base::Callback<void(const std::string& message_id,
                                            GCMClient::Result result)>;
   using GetEncryptionInfoCallback =
@@ -116,7 +117,7 @@
   // |callback|: to be called once the asynchronous operation is done.
   void Register(const std::string& app_id,
                 const std::vector<std::string>& sender_ids,
-                const RegisterCallback& callback);
+                RegisterCallback callback);
 
   // Checks that the provided |sender_ids| and |registration_id| matches the
   // stored registration info for |app_id|.
@@ -130,8 +131,7 @@
   // remove any encryption keys associated with the |app_id|.
   // |app_id|: application ID.
   // |callback|: to be called once the asynchronous operation is done.
-  void Unregister(const std::string& app_id,
-                  const UnregisterCallback& callback);
+  void Unregister(const std::string& app_id, UnregisterCallback callback);
 
   // Unregisters an (app_id, sender_id) pair from using GCM. Only works on
   // Android. Will also remove any encryption keys associated with the |app_id|.
@@ -141,7 +141,7 @@
   // |callback|: to be called once the asynchronous operation is done.
   void UnregisterWithSenderId(const std::string& app_id,
                               const std::string& sender_id,
-                              const UnregisterCallback& callback);
+                              UnregisterCallback callback);
 
   // Sends a message to a given receiver.
   // |app_id|: application ID.
@@ -317,7 +317,7 @@
   // Common code shared by Unregister and UnregisterWithSenderId.
   void UnregisterInternal(const std::string& app_id,
                           const std::string* sender_id,
-                          const UnregisterCallback& callback);
+                          UnregisterCallback callback);
 
   // Dispatches the OnMessage event to the app handler associated with |app_id|
   // if |result| indicates that it is safe to do so, or will report a decryption
@@ -331,7 +331,7 @@
   void RegisterAfterUnregister(
       const std::string& app_id,
       const std::vector<std::string>& normalized_sender_ids,
-      const UnregisterCallback& unregister_callback,
+      UnregisterCallback unregister_callback,
       GCMClient::Result result);
 
   // Callback map (from app_id to callback) for Register.
diff --git a/components/gcm_driver/gcm_driver_desktop.cc b/components/gcm_driver/gcm_driver_desktop.cc
index 4d005c5..4527066 100644
--- a/components/gcm_driver/gcm_driver_desktop.cc
+++ b/components/gcm_driver/gcm_driver_desktop.cc
@@ -865,7 +865,7 @@
     const std::string& authorized_entity,
     const std::string& scope,
     const std::map<std::string, std::string>& options,
-    const GetTokenCallback& callback) {
+    GetTokenCallback callback) {
   DCHECK(!app_id.empty());
   DCHECK(!authorized_entity.empty());
   DCHECK(!scope.empty());
@@ -877,18 +877,18 @@
     DLOG(ERROR)
         << "Unable to get the InstanceID token: cannot start the GCM Client";
 
-    callback.Run(std::string(), result);
+    std::move(callback).Run(std::string(), result);
     return;
   }
 
   // If previous GetToken operation is still in progress, bail out.
   TokenTuple tuple_key(app_id, authorized_entity, scope);
   if (get_token_callbacks_.find(tuple_key) != get_token_callbacks_.end()) {
-    callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
+    std::move(callback).Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
     return;
   }
 
-  get_token_callbacks_[tuple_key] = callback;
+  get_token_callbacks_[tuple_key] = std::move(callback);
 
   // Delay the GetToken operation until GCMClient is ready.
   if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
@@ -966,7 +966,7 @@
 void GCMDriverDesktop::DeleteToken(const std::string& app_id,
                                    const std::string& authorized_entity,
                                    const std::string& scope,
-                                   const DeleteTokenCallback& callback) {
+                                   DeleteTokenCallback callback) {
   DCHECK(!app_id.empty());
   DCHECK(!authorized_entity.empty());
   DCHECK(!scope.empty());
@@ -978,7 +978,7 @@
     DLOG(ERROR)
         << "Unable to delete the InstanceID token: cannot start the GCM Client";
 
-    callback.Run(result);
+    std::move(callback).Run(result);
     return;
   }
 
@@ -986,11 +986,11 @@
   TokenTuple tuple_key(app_id, authorized_entity, scope);
   if (delete_token_callbacks_.find(tuple_key) !=
       delete_token_callbacks_.end()) {
-    callback.Run(GCMClient::ASYNC_OPERATION_PENDING);
+    std::move(callback).Run(GCMClient::ASYNC_OPERATION_PENDING);
     return;
   }
 
-  delete_token_callbacks_[tuple_key] = callback;
+  delete_token_callbacks_[tuple_key] = std::move(callback);
 
   // Delay the DeleteToken operation until GCMClient is ready.
   if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
@@ -1141,9 +1141,9 @@
     return;
   }
 
-  GetTokenCallback callback = callback_iter->second;
+  GetTokenCallback callback = std::move(callback_iter->second);
   get_token_callbacks_.erase(callback_iter);
-  callback.Run(token, result);
+  std::move(callback).Run(token, result);
 }
 
 void GCMDriverDesktop::DeleteTokenFinished(const std::string& app_id,
@@ -1157,9 +1157,9 @@
     return;
   }
 
-  DeleteTokenCallback callback = callback_iter->second;
+  DeleteTokenCallback callback = std::move(callback_iter->second);
   delete_token_callbacks_.erase(callback_iter);
-  callback.Run(result);
+  std::move(callback).Run(result);
 }
 
 void GCMDriverDesktop::WakeFromSuspendForHeartbeat(bool wake) {
diff --git a/components/gcm_driver/gcm_driver_desktop.h b/components/gcm_driver/gcm_driver_desktop.h
index 8a2ca3e..f6e7a2f 100644
--- a/components/gcm_driver/gcm_driver_desktop.h
+++ b/components/gcm_driver/gcm_driver_desktop.h
@@ -122,7 +122,7 @@
                 const std::string& authorized_entity,
                 const std::string& scope,
                 const std::map<std::string, std::string>& options,
-                const GetTokenCallback& callback) override;
+                GetTokenCallback callback) override;
   void ValidateToken(const std::string& app_id,
                      const std::string& authorized_entity,
                      const std::string& scope,
@@ -131,7 +131,7 @@
   void DeleteToken(const std::string& app_id,
                    const std::string& authorized_entity,
                    const std::string& scope,
-                   const DeleteTokenCallback& callback) override;
+                   DeleteTokenCallback callback) override;
   void AddInstanceIDData(const std::string& app_id,
                          const std::string& instance_id,
                          const std::string& extra_data) override;
diff --git a/components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.cc b/components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.cc
index 1d79cf5..f704b3e0 100644
--- a/components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.cc
+++ b/components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.cc
@@ -61,7 +61,7 @@
     const std::string& authorized_entity,
     const std::string& scope,
     const std::map<std::string, std::string>& options,
-    const GetTokenCallback& callback) {
+    GetTokenCallback callback) {
   std::string key = app_id + authorized_entity + scope;
   auto iter = tokens_.find(key);
   std::string token;
@@ -76,7 +76,8 @@
   last_gettoken_authorized_entity_ = authorized_entity;
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(callback, token, gcm::GCMClient::SUCCESS));
+      FROM_HERE,
+      base::BindOnce(std::move(callback), token, gcm::GCMClient::SUCCESS));
 }
 
 void FakeGCMDriverForInstanceID::ValidateToken(
@@ -93,7 +94,7 @@
     const std::string& app_id,
     const std::string& authorized_entity,
     const std::string& scope,
-    const DeleteTokenCallback& callback) {
+    DeleteTokenCallback callback) {
   std::string key_prefix = app_id;
 
   // Calls to InstanceID::DeleteID() will end up deleting the token for a given
@@ -114,7 +115,7 @@
   last_deletetoken_app_id_ = app_id;
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(callback, gcm::GCMClient::SUCCESS));
+      FROM_HERE, base::BindOnce(std::move(callback), gcm::GCMClient::SUCCESS));
 }
 
 }  // namespace instance_id
diff --git a/components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h b/components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h
index f7076ab..ff428511 100644
--- a/components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h
+++ b/components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h
@@ -46,7 +46,7 @@
                 const std::string& authorized_entity,
                 const std::string& scope,
                 const std::map<std::string, std::string>& options,
-                const GetTokenCallback& callback) override;
+                GetTokenCallback callback) override;
   void ValidateToken(const std::string& app_id,
                      const std::string& authorized_entity,
                      const std::string& scope,
@@ -55,7 +55,7 @@
   void DeleteToken(const std::string& app_id,
                    const std::string& authorized_entity,
                    const std::string& scope,
-                   const DeleteTokenCallback& callback) override;
+                   DeleteTokenCallback callback) override;
   void AddInstanceIDData(const std::string& app_id,
                          const std::string& instance_id,
                          const std::string& extra_data) override;
diff --git a/components/gcm_driver/instance_id/instance_id.cc b/components/gcm_driver/instance_id/instance_id.cc
index e69bbd3..ab91121f 100644
--- a/components/gcm_driver/instance_id/instance_id.cc
+++ b/components/gcm_driver/instance_id/instance_id.cc
@@ -37,30 +37,31 @@
 
 void InstanceID::DeleteToken(const std::string& authorized_entity,
                              const std::string& scope,
-                             const DeleteTokenCallback& callback) {
+                             DeleteTokenCallback callback) {
   // Tokens with GCM scope act as Google Cloud Messaging registrations, so may
   // have associated encryption information in the GCMKeyStore. This needs to be
   // cleared when the token is deleted.
   DeleteTokenCallback wrapped_callback =
       scope == kGCMScope
-          ? base::Bind(&InstanceID::DidDelete, weak_ptr_factory_.GetWeakPtr(),
-                       authorized_entity, callback)
-          : callback;
-  DeleteTokenImpl(authorized_entity, scope, wrapped_callback);
+          ? base::BindOnce(&InstanceID::DidDelete,
+                           weak_ptr_factory_.GetWeakPtr(), authorized_entity,
+                           std::move(callback))
+          : std::move(callback);
+  DeleteTokenImpl(authorized_entity, scope, std::move(wrapped_callback));
 }
 
-void InstanceID::DeleteID(const DeleteIDCallback& callback) {
+void InstanceID::DeleteID(DeleteIDCallback callback) {
   // Use "*" as authorized_entity to remove any encryption info for all tokens.
-  DeleteIDImpl(base::Bind(&InstanceID::DidDelete,
-                          weak_ptr_factory_.GetWeakPtr(),
-                          "*" /* authorized_entity */, callback));
+  DeleteIDImpl(
+      base::BindOnce(&InstanceID::DidDelete, weak_ptr_factory_.GetWeakPtr(),
+                     "*" /* authorized_entity */, std::move(callback)));
 }
 
 void InstanceID::DidDelete(const std::string& authorized_entity,
-                           const base::Callback<void(Result result)>& callback,
+                           base::OnceCallback<void(Result result)> callback,
                            Result result) {
   gcm_driver_->GetEncryptionProviderInternal()->RemoveEncryptionInfo(
-      app_id_, authorized_entity, base::Bind(callback, result));
+      app_id_, authorized_entity, base::BindOnce(std::move(callback), result));
 }
 
 }  // namespace instance_id
diff --git a/components/gcm_driver/instance_id/instance_id.h b/components/gcm_driver/instance_id/instance_id.h
index b3d96e41..71ac3a1 100644
--- a/components/gcm_driver/instance_id/instance_id.h
+++ b/components/gcm_driver/instance_id/instance_id.h
@@ -57,12 +57,12 @@
   using GetCreationTimeCallback =
       base::Callback<void(const base::Time& creation_time)>;
   using GetTokenCallback =
-      base::Callback<void(const std::string& token, Result result)>;
+      base::OnceCallback<void(const std::string& token, Result result)>;
   using ValidateTokenCallback = base::Callback<void(bool is_valid)>;
   using GetEncryptionInfoCallback =
       base::Callback<void(const std::string&, const std::string&)>;
-  using DeleteTokenCallback = base::Callback<void(Result result)>;
-  using DeleteIDCallback = base::Callback<void(Result result)>;
+  using DeleteTokenCallback = base::OnceCallback<void(Result result)>;
+  using DeleteIDCallback = base::OnceCallback<void(Result result)>;
 
   static const int kInstanceIDByteLength = 8;
 
@@ -102,7 +102,7 @@
                         const std::string& scope,
                         const std::map<std::string, std::string>& options,
                         bool is_lazy,
-                        const GetTokenCallback& callback) = 0;
+                        GetTokenCallback callback) = 0;
 
   // Checks that the provided |token| matches the stored token for (|app_id()|,
   // |authorized_entity|, |scope|).
@@ -125,12 +125,12 @@
   // |callback|: to be called once the asynchronous operation is done.
   void DeleteToken(const std::string& authorized_entity,
                    const std::string& scope,
-                   const DeleteTokenCallback& callback);
+                   DeleteTokenCallback callback);
 
   // Resets the app instance identifier and revokes all tokens associated with
   // it.
   // |callback|: to be called once the asynchronous operation is done.
-  void DeleteID(const DeleteIDCallback& callback);
+  void DeleteID(DeleteIDCallback callback);
 
   std::string app_id() const { return app_id_; }
 
@@ -140,8 +140,8 @@
   // Platform-specific implementations.
   virtual void DeleteTokenImpl(const std::string& authorized_entity,
                                const std::string& scope,
-                               const DeleteTokenCallback& callback) = 0;
-  virtual void DeleteIDImpl(const DeleteIDCallback& callback) = 0;
+                               DeleteTokenCallback callback) = 0;
+  virtual void DeleteIDImpl(DeleteIDCallback callback) = 0;
 
   void NotifyTokenRefresh(bool update_id);
 
@@ -149,7 +149,7 @@
 
  private:
   void DidDelete(const std::string& authorized_entity,
-                 const base::Callback<void(Result result)>& callback,
+                 base::OnceCallback<void(Result result)> callback,
                  Result result);
 
   // Owned by GCMProfileServiceFactory, which is a dependency of
diff --git a/components/gcm_driver/instance_id/instance_id_android.cc b/components/gcm_driver/instance_id/instance_id_android.cc
index 06a2feaf..b2ba5857 100644
--- a/components/gcm_driver/instance_id/instance_id_android.cc
+++ b/components/gcm_driver/instance_id/instance_id_android.cc
@@ -94,13 +94,13 @@
     const std::string& scope,
     const std::map<std::string, std::string>& options,
     bool is_lazy,
-    const GetTokenCallback& callback) {
+    GetTokenCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   UMA_HISTOGRAM_COUNTS_100("InstanceID.GetToken.OptionsCount", options.size());
 
-  int32_t request_id =
-      get_token_callbacks_.Add(std::make_unique<GetTokenCallback>(callback));
+  int32_t request_id = get_token_callbacks_.Add(
+      std::make_unique<GetTokenCallback>(std::move(callback)));
 
   std::vector<std::string> options_strings;
   for (const auto& entry : options) {
@@ -127,11 +127,11 @@
 
 void InstanceIDAndroid::DeleteTokenImpl(const std::string& authorized_entity,
                                         const std::string& scope,
-                                        const DeleteTokenCallback& callback) {
+                                        DeleteTokenCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   int32_t request_id = delete_token_callbacks_.Add(
-      std::make_unique<DeleteTokenCallback>(callback));
+      std::make_unique<DeleteTokenCallback>(std::move(callback)));
 
   JNIEnv* env = AttachCurrentThread();
   Java_InstanceIDBridge_deleteToken(
@@ -140,11 +140,11 @@
       ConvertUTF8ToJavaString(env, scope));
 }
 
-void InstanceIDAndroid::DeleteIDImpl(const DeleteIDCallback& callback) {
+void InstanceIDAndroid::DeleteIDImpl(DeleteIDCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   int32_t request_id = delete_id_callbacks_.Add(
-      std::make_unique<DeleteIDCallback>(DeleteIDCallback(callback)));
+      std::make_unique<DeleteIDCallback>(std::move(callback)));
 
   JNIEnv* env = AttachCurrentThread();
   Java_InstanceIDBridge_deleteInstanceID(env, java_ref_, request_id);
@@ -195,7 +195,7 @@
   GetTokenCallback* callback = get_token_callbacks_.Lookup(request_id);
   DCHECK(callback);
   std::string token = ConvertJavaStringToUTF8(jtoken);
-  callback->Run(
+  std::move(*callback).Run(
       token, token.empty() ? InstanceID::UNKNOWN_ERROR : InstanceID::SUCCESS);
   get_token_callbacks_.Remove(request_id);
 }
@@ -209,7 +209,8 @@
 
   DeleteTokenCallback* callback = delete_token_callbacks_.Lookup(request_id);
   DCHECK(callback);
-  callback->Run(success ? InstanceID::SUCCESS : InstanceID::UNKNOWN_ERROR);
+  std::move(*callback).Run(success ? InstanceID::SUCCESS
+                                   : InstanceID::UNKNOWN_ERROR);
   delete_token_callbacks_.Remove(request_id);
 }
 
@@ -222,7 +223,8 @@
 
   DeleteIDCallback* callback = delete_id_callbacks_.Lookup(request_id);
   DCHECK(callback);
-  callback->Run(success ? InstanceID::SUCCESS : InstanceID::UNKNOWN_ERROR);
+  std::move(*callback).Run(success ? InstanceID::SUCCESS
+                                   : InstanceID::UNKNOWN_ERROR);
   delete_id_callbacks_.Remove(request_id);
 }
 
diff --git a/components/gcm_driver/instance_id/instance_id_android.h b/components/gcm_driver/instance_id/instance_id_android.h
index bb9d0487..d82c039 100644
--- a/components/gcm_driver/instance_id/instance_id_android.h
+++ b/components/gcm_driver/instance_id/instance_id_android.h
@@ -47,15 +47,15 @@
                 const std::string& scope,
                 const std::map<std::string, std::string>& options,
                 bool is_lazy,
-                const GetTokenCallback& callback) override;
+                GetTokenCallback callback) override;
   void ValidateToken(const std::string& authorized_entity,
                      const std::string& scope,
                      const std::string& token,
                      const ValidateTokenCallback& callback) override;
   void DeleteTokenImpl(const std::string& audience,
                        const std::string& scope,
-                       const DeleteTokenCallback& callback) override;
-  void DeleteIDImpl(const DeleteIDCallback& callback) override;
+                       DeleteTokenCallback callback) override;
+  void DeleteIDImpl(DeleteIDCallback callback) override;
 
   // Methods called from Java via JNI:
   void DidGetID(JNIEnv* env,
diff --git a/components/gcm_driver/instance_id/instance_id_impl.cc b/components/gcm_driver/instance_id/instance_id_impl.cc
index 3576f875..5155e97 100644
--- a/components/gcm_driver/instance_id/instance_id_impl.cc
+++ b/components/gcm_driver/instance_id/instance_id_impl.cc
@@ -79,8 +79,8 @@
 }
 
 void InstanceIDImpl::GetCreationTime(const GetCreationTimeCallback& callback) {
-  RunWhenReady(base::Bind(&InstanceIDImpl::DoGetCreationTime,
-                          weak_ptr_factory_.GetWeakPtr(), callback));
+  RunWhenReady(base::BindOnce(&InstanceIDImpl::DoGetCreationTime,
+                              weak_ptr_factory_.GetWeakPtr(), callback));
 }
 
 void InstanceIDImpl::DoGetCreationTime(
@@ -92,27 +92,28 @@
                               const std::string& scope,
                               const std::map<std::string, std::string>& options,
                               bool is_lazy,
-                              const GetTokenCallback& callback) {
+                              GetTokenCallback callback) {
   DCHECK(!authorized_entity.empty());
   DCHECK(!scope.empty());
 
   UMA_HISTOGRAM_COUNTS_100("InstanceID.GetToken.OptionsCount", options.size());
 
-  RunWhenReady(base::Bind(&InstanceIDImpl::DoGetToken,
-                          weak_ptr_factory_.GetWeakPtr(), authorized_entity,
-                          scope, options, callback));
+  RunWhenReady(base::BindOnce(&InstanceIDImpl::DoGetToken,
+                              weak_ptr_factory_.GetWeakPtr(), authorized_entity,
+                              scope, options, std::move(callback)));
 }
 
 void InstanceIDImpl::DoGetToken(
     const std::string& authorized_entity,
     const std::string& scope,
     const std::map<std::string, std::string>& options,
-    const GetTokenCallback& callback) {
+    GetTokenCallback callback) {
   EnsureIDGenerated();
 
-  Handler()->GetToken(app_id(), authorized_entity, scope, options,
-                      base::Bind(&InstanceIDImpl::OnGetTokenCompleted,
-                                 weak_ptr_factory_.GetWeakPtr(), callback));
+  Handler()->GetToken(
+      app_id(), authorized_entity, scope, options,
+      base::BindOnce(&InstanceIDImpl::OnGetTokenCompleted,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
 void InstanceIDImpl::ValidateToken(const std::string& authorized_entity,
@@ -123,9 +124,9 @@
   DCHECK(!scope.empty());
   DCHECK(!token.empty());
 
-  RunWhenReady(base::Bind(&InstanceIDImpl::DoValidateToken,
-                          weak_ptr_factory_.GetWeakPtr(), authorized_entity,
-                          scope, token, callback));
+  RunWhenReady(base::BindOnce(&InstanceIDImpl::DoValidateToken,
+                              weak_ptr_factory_.GetWeakPtr(), authorized_entity,
+                              scope, token, callback));
 }
 
 void InstanceIDImpl::DoValidateToken(const std::string& authorized_entity,
@@ -142,45 +143,47 @@
 
 void InstanceIDImpl::DeleteTokenImpl(const std::string& authorized_entity,
                                      const std::string& scope,
-                                     const DeleteTokenCallback& callback) {
+                                     DeleteTokenCallback callback) {
   DCHECK(!authorized_entity.empty());
   DCHECK(!scope.empty());
 
-  RunWhenReady(base::Bind(&InstanceIDImpl::DoDeleteToken,
-                          weak_ptr_factory_.GetWeakPtr(), authorized_entity,
-                          scope, callback));
+  RunWhenReady(base::BindOnce(&InstanceIDImpl::DoDeleteToken,
+                              weak_ptr_factory_.GetWeakPtr(), authorized_entity,
+                              scope, std::move(callback)));
 }
 
-void InstanceIDImpl::DoDeleteToken(
-    const std::string& authorized_entity,
-    const std::string& scope,
-    const DeleteTokenCallback& callback) {
+void InstanceIDImpl::DoDeleteToken(const std::string& authorized_entity,
+                                   const std::string& scope,
+                                   DeleteTokenCallback callback) {
   // Nothing to delete if the ID has not been generated.
   if (id_.empty()) {
-    callback.Run(InstanceID::INVALID_PARAMETER);
+    std::move(callback).Run(InstanceID::INVALID_PARAMETER);
     return;
   }
 
-  Handler()->DeleteToken(app_id(), authorized_entity, scope,
-                        base::Bind(&InstanceIDImpl::OnDeleteTokenCompleted,
-                                   weak_ptr_factory_.GetWeakPtr(), callback));
+  Handler()->DeleteToken(
+      app_id(), authorized_entity, scope,
+      base::BindOnce(&InstanceIDImpl::OnDeleteTokenCompleted,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
-void InstanceIDImpl::DeleteIDImpl(const DeleteIDCallback& callback) {
-  RunWhenReady(base::Bind(&InstanceIDImpl::DoDeleteID,
-                          weak_ptr_factory_.GetWeakPtr(), callback));
+void InstanceIDImpl::DeleteIDImpl(DeleteIDCallback callback) {
+  RunWhenReady(base::BindOnce(&InstanceIDImpl::DoDeleteID,
+                              weak_ptr_factory_.GetWeakPtr(),
+                              std::move(callback)));
 }
 
-void InstanceIDImpl::DoDeleteID(const DeleteIDCallback& callback) {
+void InstanceIDImpl::DoDeleteID(DeleteIDCallback callback) {
   // Nothing to do if ID has not been generated.
   if (id_.empty()) {
-    callback.Run(InstanceID::SUCCESS);
+    std::move(callback).Run(InstanceID::SUCCESS);
     return;
   }
 
   Handler()->DeleteAllTokensForApp(
-      app_id(), base::Bind(&InstanceIDImpl::OnDeleteIDCompleted,
-                           weak_ptr_factory_.GetWeakPtr(), callback));
+      app_id(),
+      base::BindOnce(&InstanceIDImpl::OnDeleteIDCompleted,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 
   Handler()->RemoveInstanceIDData(app_id());
 
@@ -188,22 +191,20 @@
   creation_time_ = base::Time();
 }
 
-void InstanceIDImpl::OnGetTokenCompleted(const GetTokenCallback& callback,
+void InstanceIDImpl::OnGetTokenCompleted(GetTokenCallback callback,
                                          const std::string& token,
                                          gcm::GCMClient::Result result) {
-  callback.Run(token, GCMClientResultToInstanceIDResult(result));
+  std::move(callback).Run(token, GCMClientResultToInstanceIDResult(result));
 }
 
-void InstanceIDImpl::OnDeleteTokenCompleted(
-    const DeleteTokenCallback& callback,
-    gcm::GCMClient::Result result) {
-  callback.Run(GCMClientResultToInstanceIDResult(result));
+void InstanceIDImpl::OnDeleteTokenCompleted(DeleteTokenCallback callback,
+                                            gcm::GCMClient::Result result) {
+  std::move(callback).Run(GCMClientResultToInstanceIDResult(result));
 }
 
-void InstanceIDImpl::OnDeleteIDCompleted(
-    const DeleteIDCallback& callback,
-    gcm::GCMClient::Result result) {
-  callback.Run(GCMClientResultToInstanceIDResult(result));
+void InstanceIDImpl::OnDeleteIDCompleted(DeleteIDCallback callback,
+                                         gcm::GCMClient::Result result) {
+  std::move(callback).Run(GCMClientResultToInstanceIDResult(result));
 }
 
 void InstanceIDImpl::GetInstanceIDDataCompleted(
@@ -266,11 +267,11 @@
   return handler;
 }
 
-void InstanceIDImpl::RunWhenReady(base::Closure task) {
+void InstanceIDImpl::RunWhenReady(base::OnceClosure task) {
   if (!delayed_task_controller_.CanRunTaskWithoutDelay())
-    delayed_task_controller_.AddTask(task);
+    delayed_task_controller_.AddTask(std::move(task));
   else
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(task));
 }
 
 }  // namespace instance_id
diff --git a/components/gcm_driver/instance_id/instance_id_impl.h b/components/gcm_driver/instance_id/instance_id_impl.h
index 5e1c8bc..80e9282 100644
--- a/components/gcm_driver/instance_id/instance_id_impl.h
+++ b/components/gcm_driver/instance_id/instance_id_impl.h
@@ -37,49 +37,48 @@
                 const std::string& scope,
                 const std::map<std::string, std::string>& options,
                 bool is_lazy,
-                const GetTokenCallback& callback) override;
+                GetTokenCallback callback) override;
   void ValidateToken(const std::string& authorized_entity,
                      const std::string& scope,
                      const std::string& token,
                      const ValidateTokenCallback& callback) override;
   void DeleteTokenImpl(const std::string& authorized_entity,
                        const std::string& scope,
-                       const DeleteTokenCallback& callback) override;
-  void DeleteIDImpl(const DeleteIDCallback& callback) override;
+                       DeleteTokenCallback callback) override;
+  void DeleteIDImpl(DeleteIDCallback callback) override;
 
  private:
   void EnsureIDGenerated();
 
-  void OnGetTokenCompleted(const GetTokenCallback& callback,
+  void OnGetTokenCompleted(GetTokenCallback callback,
                            const std::string& token,
                            gcm::GCMClient::Result result);
-  void OnDeleteTokenCompleted(const DeleteTokenCallback& callback,
+  void OnDeleteTokenCompleted(DeleteTokenCallback callback,
                               gcm::GCMClient::Result result);
-  void OnDeleteIDCompleted(const DeleteIDCallback& callback,
+  void OnDeleteIDCompleted(DeleteIDCallback callback,
                            gcm::GCMClient::Result result);
   void GetInstanceIDDataCompleted(const std::string& instance_id,
                                   const std::string& extra_data);
 
   void DoGetID(const GetIDCallback& callback);
   void DoGetCreationTime(const GetCreationTimeCallback& callback);
-  void DoGetToken(
-      const std::string& authorized_entity,
-      const std::string& scope,
-      const std::map<std::string, std::string>& options,
-      const GetTokenCallback& callback);
+  void DoGetToken(const std::string& authorized_entity,
+                  const std::string& scope,
+                  const std::map<std::string, std::string>& options,
+                  GetTokenCallback callback);
   void DoValidateToken(const std::string& authorized_entity,
                        const std::string& scope,
                        const std::string& token,
                        const ValidateTokenCallback& callback);
   void DoDeleteToken(const std::string& authorized_entity,
                      const std::string& scope,
-                     const DeleteTokenCallback& callback);
-  void DoDeleteID(const DeleteIDCallback& callback);
+                     DeleteTokenCallback callback);
+  void DoDeleteID(DeleteIDCallback callback);
 
   gcm::InstanceIDHandler* Handler();
 
   // Asynchronously runs task once delayed_task_controller_ is ready.
-  void RunWhenReady(base::Closure task);
+  void RunWhenReady(base::OnceClosure task);
 
   gcm::GCMDelayedTaskController delayed_task_controller_;
 
diff --git a/components/invalidation/impl/fcm_invalidation_service_unittest.cc b/components/invalidation/impl/fcm_invalidation_service_unittest.cc
index 3f595c80..30a1637 100644
--- a/components/invalidation/impl/fcm_invalidation_service_unittest.cc
+++ b/components/invalidation/impl/fcm_invalidation_service_unittest.cc
@@ -49,12 +49,19 @@
 
   MOCK_METHOD1(GetID, void(const GetIDCallback& callback));
   MOCK_METHOD1(GetCreationTime, void(const GetCreationTimeCallback& callback));
-  MOCK_METHOD5(GetToken,
+  void GetToken(const std::string& authorized_entity,
+                const std::string& scope,
+                const std::map<std::string, std::string>& options,
+                bool is_lazy,
+                GetTokenCallback callback) override {
+    GetToken_(authorized_entity, scope, options, is_lazy, callback);
+  }
+  MOCK_METHOD5(GetToken_,
                void(const std::string& authorized_entity,
                     const std::string& scope,
                     const std::map<std::string, std::string>& options,
                     bool is_lazy,
-                    const GetTokenCallback& callback));
+                    GetTokenCallback& callback));
   MOCK_METHOD4(ValidateToken,
                void(const std::string& authorized_entity,
                     const std::string& scope,
@@ -62,11 +69,19 @@
                     const ValidateTokenCallback& callback));
 
  protected:
-  MOCK_METHOD3(DeleteTokenImpl,
+  void DeleteTokenImpl(const std::string& authorized_entity,
+                       const std::string& scope,
+                       DeleteTokenCallback callback) override {
+    DeleteTokenImpl_(authorized_entity, scope, callback);
+  }
+  MOCK_METHOD3(DeleteTokenImpl_,
                void(const std::string& authorized_entity,
                     const std::string& scope,
-                    const DeleteTokenCallback& callback));
-  MOCK_METHOD1(DeleteIDImpl, void(const DeleteIDCallback& callback));
+                    DeleteTokenCallback& callback));
+  void DeleteIDImpl(DeleteIDCallback callback) override {
+    DeleteIDImpl_(callback);
+  }
+  MOCK_METHOD1(DeleteIDImpl_, void(DeleteIDCallback& callback));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockInstanceID);
diff --git a/components/invalidation/impl/fcm_network_handler_unittests.cc b/components/invalidation/impl/fcm_network_handler_unittests.cc
index eb1b654..41decf4 100644
--- a/components/invalidation/impl/fcm_network_handler_unittests.cc
+++ b/components/invalidation/impl/fcm_network_handler_unittests.cc
@@ -63,12 +63,19 @@
 
   MOCK_METHOD1(GetID, void(const GetIDCallback& callback));
   MOCK_METHOD1(GetCreationTime, void(const GetCreationTimeCallback& callback));
-  MOCK_METHOD5(GetToken,
+  void GetToken(const std::string& authorized_entity,
+                const std::string& scope,
+                const std::map<std::string, std::string>& options,
+                bool is_lazy,
+                GetTokenCallback callback) override {
+    GetToken_(authorized_entity, scope, options, is_lazy, callback);
+  }
+  MOCK_METHOD5(GetToken_,
                void(const std::string& authorized_entity,
                     const std::string& scope,
                     const std::map<std::string, std::string>& options,
                     bool is_lazy,
-                    const GetTokenCallback& callback));
+                    GetTokenCallback& callback));
   MOCK_METHOD4(ValidateToken,
                void(const std::string& authorized_entity,
                     const std::string& scope,
@@ -76,11 +83,19 @@
                     const ValidateTokenCallback& callback));
 
  protected:
-  MOCK_METHOD3(DeleteTokenImpl,
+  void DeleteTokenImpl(const std::string& authorized_entity,
+                       const std::string& scope,
+                       DeleteTokenCallback callback) override {
+    DeleteTokenImpl_(authorized_entity, scope, callback);
+  }
+  MOCK_METHOD3(DeleteTokenImpl_,
                void(const std::string& authorized_entity,
                     const std::string& scope,
-                    const DeleteTokenCallback& callback));
-  MOCK_METHOD1(DeleteIDImpl, void(const DeleteIDCallback& callback));
+                    DeleteTokenCallback& callback));
+  void DeleteIDImpl(DeleteIDCallback callback) override {
+    DeleteIDImpl_(callback);
+  }
+  MOCK_METHOD1(DeleteIDImpl_, void(DeleteIDCallback& callback));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockInstanceID);
@@ -198,13 +213,13 @@
 ACTION_TEMPLATE(InvokeCallbackArgument,
                 HAS_1_TEMPLATE_PARAMS(int, k),
                 AND_1_VALUE_PARAMS(p0)) {
-  std::get<k>(args).Run(p0);
+  std::move(std::get<k>(args)).Run(p0);
 }
 
 ACTION_TEMPLATE(InvokeCallbackArgument,
                 HAS_1_TEMPLATE_PARAMS(int, k),
                 AND_2_VALUE_PARAMS(p0, p1)) {
-  std::get<k>(args).Run(p0, p1);
+  std::move(std::get<k>(args)).Run(p0, p1);
 }
 
 }  // namespace
@@ -234,7 +249,7 @@
       MessageCallback mock_on_message_callback) {
     std::unique_ptr<FCMNetworkHandler> handler = MakeHandler();
     handler->SetMessageReceiver(mock_on_message_callback);
-    EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+    EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
         .WillOnce(
             InvokeCallbackArgument<4>("token", InstanceID::Result::SUCCESS));
     handler->StartListening();
@@ -272,7 +287,7 @@
   handler->SetTokenReceiver(mock_on_token_callback.Get());
 
   // Check that the handler gets the token through GetToken.
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token", InstanceID::Result::SUCCESS));
   EXPECT_CALL(mock_on_token_callback, Run("token")).Times(1);
@@ -285,7 +300,7 @@
   MockOnTokenCallback mock_on_token_callback;
 
   // Check that the handler gets the token through GetToken.
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token", InstanceID::Result::SUCCESS));
   EXPECT_CALL(mock_on_token_callback, Run(_)).Times(0);
@@ -302,7 +317,7 @@
   std::unique_ptr<FCMNetworkHandler> handler = MakeHandler();
   EXPECT_CALL(mock_on_message_callback, Run(_, _, _, _)).Times(0);
   handler->SetMessageReceiver(mock_on_message_callback.Get());
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token", InstanceID::Result::SUCCESS));
 
@@ -398,7 +413,7 @@
   handler->SetTokenReceiver(mock_on_token_callback.Get());
 
   // Check that after StartListening we receive the token and store it.
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token", InstanceID::Result::SUCCESS));
   EXPECT_CALL(mock_on_token_callback, Run("token")).Times(1);
@@ -413,7 +428,7 @@
 
   // Check that after StartListening the token will be requested, depite we have
   // saved token.
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token_new", InstanceID::Result::SUCCESS));
   EXPECT_CALL(mock_on_token_callback, Run("token_new")).Times(1);
@@ -430,7 +445,7 @@
 
   // Checking that after start listening the token will be requested
   // and passed to the appropriate token receiver.
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token", InstanceID::Result::SUCCESS));
   EXPECT_CALL(*mock_instance_id(), ValidateToken(_, _, _, _)).Times(0);
@@ -444,7 +459,7 @@
   task_runner->FastForwardBy(time_to_validation -
                              base::TimeDelta::FromSeconds(1));
   // But when it is time, validation happens.
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token_new", InstanceID::Result::SUCCESS));
   EXPECT_CALL(mock_on_token_callback, Run("token_new")).Times(1);
@@ -461,7 +476,7 @@
 
   // Checking that after start listening the token will be requested
   // and passed to the appropriate token receiver
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token", InstanceID::Result::SUCCESS));
   EXPECT_CALL(*mock_instance_id(), ValidateToken(_, _, _, _)).Times(0);
@@ -476,7 +491,7 @@
                              base::TimeDelta::FromSeconds(1));
 
   // But when it is time, validation happens.
-  EXPECT_CALL(*mock_instance_id(), GetToken(_, _, _, _, _))
+  EXPECT_CALL(*mock_instance_id(), GetToken_(_, _, _, _, _))
       .WillOnce(
           InvokeCallbackArgument<4>("token", InstanceID::Result::SUCCESS));
   EXPECT_CALL(mock_on_token_callback, Run(_)).Times(0);
diff --git a/components/offline_pages/core/prefetch/prefetch_gcm_app_handler.cc b/components/offline_pages/core/prefetch/prefetch_gcm_app_handler.cc
index 044c652..1d30402d 100644
--- a/components/offline_pages/core/prefetch/prefetch_gcm_app_handler.cc
+++ b/components/offline_pages/core/prefetch/prefetch_gcm_app_handler.cc
@@ -26,7 +26,7 @@
 
 void PrefetchGCMAppHandler::GetGCMToken(
     instance_id::InstanceID::GetTokenCallback callback) {
-  token_factory_->GetGCMToken(callback);
+  token_factory_->GetGCMToken(std::move(callback));
 }
 
 void PrefetchGCMAppHandler::ShutdownHandler() {
diff --git a/components/offline_pages/core/prefetch/prefetch_gcm_app_handler_unittest.cc b/components/offline_pages/core/prefetch/prefetch_gcm_app_handler_unittest.cc
index 3b894b9..b4d6753 100644
--- a/components/offline_pages/core/prefetch/prefetch_gcm_app_handler_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_gcm_app_handler_unittest.cc
@@ -23,7 +23,7 @@
 
   void GetGCMToken(
       instance_id::InstanceID::GetTokenCallback callback) override {
-    callback.Run(token, result);
+    std::move(callback).Run(token, result);
   }
 
   instance_id::InstanceID::Result result = instance_id::InstanceID::SUCCESS;
@@ -103,10 +103,10 @@
 TEST_F(PrefetchGCMAppHandlerTest, TestGetToken) {
   std::string result_token;
 
-  handler()->GetGCMToken(base::AdaptCallbackForRepeating(base::BindOnce(
+  handler()->GetGCMToken(base::BindOnce(
       [](std::string* result_token, const std::string& token,
          instance_id::InstanceID::Result result) { *result_token = token; },
-      &result_token)));
+      &result_token));
   EXPECT_EQ(token_factory()->token, result_token);
 }
 
diff --git a/components/offline_pages/core/prefetch/test_prefetch_gcm_handler.cc b/components/offline_pages/core/prefetch/test_prefetch_gcm_handler.cc
index 494d6ac1..50f77c3 100644
--- a/components/offline_pages/core/prefetch/test_prefetch_gcm_handler.cc
+++ b/components/offline_pages/core/prefetch/test_prefetch_gcm_handler.cc
@@ -22,7 +22,7 @@
 
 void TestPrefetchGCMHandler::GetGCMToken(
     instance_id::InstanceID::GetTokenCallback callback) {
-  callback.Run(kToken, instance_id::InstanceID::Result::SUCCESS);
+  std::move(callback).Run(kToken, instance_id::InstanceID::Result::SUCCESS);
 }
 
 void TestPrefetchGCMHandler::SetService(PrefetchService* service) {}
diff --git a/components/omnibox/browser/bookmark_provider.cc b/components/omnibox/browser/bookmark_provider.cc
index 7e21cffe..70eaeaa 100644
--- a/components/omnibox/browser/bookmark_provider.cc
+++ b/components/omnibox/browser/bookmark_provider.cc
@@ -17,6 +17,7 @@
 #include "components/bookmarks/browser/titled_url_match.h"
 #include "components/omnibox/browser/autocomplete_provider_client.h"
 #include "components/omnibox/browser/autocomplete_result.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/omnibox/browser/titled_url_match_utils.h"
 #include "components/prefs/pref_service.h"
 #include "components/query_parser/snippet.h"
@@ -66,6 +67,7 @@
   //  - Terms must be at least three characters in length in order to perform
   //    partial word matches. Any term of lesser length will only be used as an
   //    exact match. 'def' will match against 'define' but 'de' will not match.
+  //    (The flag below changes this behavior.)
   //  - A search containing multiple terms will return results with those words
   //    occuring in any order.
   //  - Terms enclosed in quotes comprises a phrase that must match exactly.
@@ -75,9 +77,12 @@
   // Please refer to the code for TitledUrlIndex::GetResultsMatching for
   // complete details of how searches are performed against the user's
   // bookmarks.
-  bookmark_model_->GetBookmarksMatching(input.text(),
-                                        kMaxBookmarkMatches,
-                                        &matches);
+  bookmark_model_->GetBookmarksMatching(
+      input.text(), kMaxBookmarkMatches,
+      OmniboxFieldTrial::IsShortBookmarkSuggestionsEnabled()
+          ? query_parser::MatchingAlgorithm::ALWAYS_PREFIX_SEARCH
+          : query_parser::MatchingAlgorithm::DEFAULT,
+      &matches);
   if (matches.empty())
     return;  // There were no matches.
   const base::string16 fixed_up_input(FixupUserInput(input).second);
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index 3aba494c..6191530 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -558,6 +558,11 @@
   return base::FeatureList::IsEnabled(omnibox::kOmniboxReverseAnswers);
 }
 
+bool OmniboxFieldTrial::IsShortBookmarkSuggestionsEnabled() {
+  return base::FeatureList::IsEnabled(
+      omnibox::kOmniboxShortBookmarkSuggestions);
+}
+
 bool OmniboxFieldTrial::IsTabSwitchSuggestionsEnabled() {
   return base::FeatureList::IsEnabled(omnibox::kOmniboxTabSwitchSuggestions);
 }
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index 0d35b71..d8143e32 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -386,6 +386,9 @@
 // Returns true if the reverse answers flag is enabled.
 bool IsReverseAnswersEnabled();
 
+// Returns true if the short bookmark suggestions flag is enabled.
+bool IsShortBookmarkSuggestionsEnabled();
+
 // Returns true if either the tab switch suggestions flag is enabled.
 bool IsTabSwitchSuggestionsEnabled();
 
diff --git a/components/omnibox/browser/omnibox_pedal_implementations.cc b/components/omnibox/browser/omnibox_pedal_implementations.cc
index 80c65fd..b61ea7e 100644
--- a/components/omnibox/browser/omnibox_pedal_implementations.cc
+++ b/components/omnibox/browser/omnibox_pedal_implementations.cc
@@ -142,7 +142,7 @@
 GetPedalImplementations() {
   std::unordered_map<OmniboxPedalId, std::unique_ptr<OmniboxPedal>> pedals;
   const auto add = [&](OmniboxPedalId id, OmniboxPedal* pedal) {
-    pedals.insert({id, std::unique_ptr<OmniboxPedal>(pedal)});
+    pedals.insert(std::make_pair(id, std::unique_ptr<OmniboxPedal>(pedal)));
   };
   add(OmniboxPedalId::CLEAR_BROWSING_DATA, new OmniboxPedalClearBrowsingData());
   add(OmniboxPedalId::CHANGE_SEARCH_ENGINE,
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index 79adb02..5a053ff 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -78,6 +78,10 @@
 const base::Feature kOmniboxReverseAnswers{"OmniboxReverseAnswers",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature used to enable matching short words to bookmarks for suggestions.
+const base::Feature kOmniboxShortBookmarkSuggestions{
+    "OmniboxShortBookmarkSuggestions", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Feature used to force on the experiment of transmission of tail suggestions
 // from GWS to this client, currently testing for desktop.
 const base::Feature kOmniboxTailSuggestions{
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h
index b5416dba..9711a32 100644
--- a/components/omnibox/common/omnibox_features.h
+++ b/components/omnibox/common/omnibox_features.h
@@ -20,6 +20,7 @@
 extern const base::Feature kOmniboxRichEntitySuggestions;
 extern const base::Feature kOmniboxNewAnswerLayout;
 extern const base::Feature kOmniboxReverseAnswers;
+extern const base::Feature kOmniboxShortBookmarkSuggestions;
 extern const base::Feature kOmniboxTailSuggestions;
 extern const base::Feature kOmniboxTabSwitchSuggestions;
 extern const base::Feature kOmniboxReverseTabSwitchLogic;
diff --git a/components/password_manager/core/browser/new_password_form_manager.cc b/components/password_manager/core/browser/new_password_form_manager.cc
index aeba7c68..ea4fdc5 100644
--- a/components/password_manager/core/browser/new_password_form_manager.cc
+++ b/components/password_manager/core/browser/new_password_form_manager.cc
@@ -394,8 +394,16 @@
 
   if (!new_blacklisted_) {
     new_blacklisted_ = std::make_unique<PasswordForm>();
-    new_blacklisted_->origin = observed_form_.url;
-    new_blacklisted_->signon_realm = GetSignonRealm(observed_form_.url);
+    if (IsHttpAuth()) {
+      new_blacklisted_->origin = observed_http_auth_digest_->origin;
+      // GetSignonRealm is not suitable for http auth credentials.
+      new_blacklisted_->signon_realm = observed_http_auth_digest_->signon_realm;
+      new_blacklisted_->scheme = observed_http_auth_digest_->scheme;
+    } else {
+      new_blacklisted_->origin = observed_form_.url;
+      new_blacklisted_->signon_realm = GetSignonRealm(observed_form_.url);
+      new_blacklisted_->scheme = PasswordForm::SCHEME_HTML;
+    }
     blacklisted_matches_.push_back(new_blacklisted_.get());
   }
   form_saver_->PermanentlyBlacklist(new_blacklisted_.get());
diff --git a/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
index 91d2d6f..956029d0 100644
--- a/components/password_manager/core/browser/new_password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -1939,6 +1939,31 @@
   EXPECT_TRUE(credentials_to_update.empty());
 }
 
+TEST_F(NewPasswordFormManagerTest, BlacklistHttpAuthCredentials) {
+  PasswordForm http_auth_form = parsed_observed_form_;
+  http_auth_form.signon_realm += "my-auth-realm";
+  http_auth_form.scheme = PasswordForm::SCHEME_BASIC;
+
+  CreateFormManagerForHttpAuthForm(http_auth_form);
+  MockFormSaver& form_saver = MockFormSaver::Get(form_manager_.get());
+
+  // Simulate that the user submits http auth credentials.
+  http_auth_form.username_value = ASCIIToUTF16("user1");
+  http_auth_form.password_value = ASCIIToUTF16("pass1");
+  ASSERT_TRUE(
+      form_manager_->ProvisionallySaveHttpAuthFormIfIsManaged(http_auth_form));
+
+  // Simulate that the user clicks never.
+  PasswordForm blacklisted_form;
+  EXPECT_CALL(form_saver, PermanentlyBlacklist(_))
+      .WillOnce(SaveArgPointee<0>(&blacklisted_form));
+  form_manager_->OnNeverClicked();
+
+  EXPECT_EQ(http_auth_form.signon_realm, blacklisted_form.signon_realm);
+  EXPECT_EQ(http_auth_form.origin, blacklisted_form.origin);
+  EXPECT_EQ(http_auth_form.scheme, blacklisted_form.scheme);
+}
+
 }  // namespace
 
 }  // namespace password_manager
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 998043c..01ded43 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -607,6 +607,7 @@
         'HighContrastEnabled',
         'VirtualKeyboardEnabled',
         'StickyKeysEnabled',
+        'DockedMagnifierEnabled',
         'KeyboardDefaultToFunctionKeys',
         'ScreenMagnifierType',
         'DeviceLoginScreenDefaultLargeCursorEnabled',
@@ -3637,7 +3638,7 @@
             'properties': {
               'installation_mode': {
                 'type': 'string',
-                'enum': ['blocked', 'allowed', 'force_installed', 'normal_installed']
+                'enum': ['blocked', 'allowed', 'force_installed', 'normal_installed', 'removed']
               },
               'update_url': { 'type': 'string' },
               'blocked_permissions': {
@@ -3666,7 +3667,8 @@
                 '$ref': 'ListOfUrlPatterns'
               },
               'blocked_install_message': {
-                'type': 'string'
+                'type': 'string',
+                'description': '''text that will be displayed to the user in the chrome webstore if installation is blocked.''',
               }
             },
           },
@@ -3747,6 +3749,10 @@
           'allowed_permissions': ['downloads'],
           'installation_mode': 'allowed',
         },
+        'fghijklmnopabcdefghijklmnopabcde' : {
+          'installation_mode': 'removed',
+          'blocked_install_message': 'Custom removal message.',
+        },
         '*': {
           'installation_mode': 'blocked',
           'blocked_permissions': ['downloads', 'bookmarks'],
@@ -9242,6 +9248,30 @@
           If this policy is left unset, the sticky keys is disabled initially but can be enabled by the user anytime.'''
     },
     {
+      'name': 'DockedMagnifierEnabled',
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome_os:76-'],
+      'features': {
+        'can_be_recommended': True,
+        'dynamic_refresh': True,
+        'per_profile': True,
+      },
+      'example_value': True,
+      'id': 562,
+      'caption': '''Enable docked magnifier''',
+      'tags': [],
+      'desc': '''Enable the docked magnifier accessibility feature.
+
+          If this policy is set to true, the docked magnifier will always be enabled.
+
+          If this policy is set to false, the docked magnifier will always be disabled.
+
+          If you set this policy, users cannot change or override it.
+
+          If this policy is left unset, the docked magnifier is disabled initially but can be enabled by the user anytime.'''
+    },
+    {
       'name': 'KeyboardDefaultToFunctionKeys',
       'type': 'main',
       'schema': { 'type': 'boolean' },
@@ -16589,5 +16619,5 @@
   ],
   'placeholders': [],
   'deleted_policy_ids': [412],
-  'highest_id_currently_used':  561
+  'highest_id_currently_used':  562
 }
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc
index fa0a0d5..034df22 100644
--- a/components/signin/core/browser/about_signin_internals.cc
+++ b/components/signin/core/browser/about_signin_internals.cc
@@ -580,30 +580,34 @@
                   TokenServiceLoadCredentialsStateToLabel(load_tokens_state));
 
   if (identity_manager->HasPrimaryAccount()) {
-    std::string account_id = identity_manager->GetPrimaryAccountId();
+    CoreAccountInfo account_info = identity_manager->GetPrimaryAccountInfo();
     AddSectionEntry(basic_info,
                     SigninStatusFieldToLabel(signin_internals_util::ACCOUNT_ID),
-                    account_id);
-    AddSectionEntry(
-        basic_info, SigninStatusFieldToLabel(signin_internals_util::GAIA_ID),
-        identity_manager
-            ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id)
-            ->gaia);
+                    account_info.account_id);
+    AddSectionEntry(basic_info,
+                    SigninStatusFieldToLabel(signin_internals_util::GAIA_ID),
+                    account_info.gaia);
     AddSectionEntry(basic_info,
                     SigninStatusFieldToLabel(signin_internals_util::USERNAME),
-                    identity_manager->GetPrimaryAccountInfo().email);
+                    account_info.email);
     if (signin_error_controller->HasError()) {
       const std::string error_account_id =
           signin_error_controller->error_account_id();
-      const std::string error_username =
+      const base::Optional<AccountInfo> error_account_info =
           identity_manager
               ->FindAccountInfoForAccountWithRefreshTokenByAccountId(
-                  error_account_id)
-              ->email;
+                  error_account_id);
       AddSectionEntry(basic_info, "Auth Error",
           signin_error_controller->auth_error().ToString());
       AddSectionEntry(basic_info, "Auth Error Account Id", error_account_id);
-      AddSectionEntry(basic_info, "Auth Error Username", error_username);
+
+      // The error_account_info optional should never be unset when we reach
+      // this line (as we should have a refresh token, even if in an error
+      // state). However, since this is a debug page, make the code resilient
+      // to avoid rendering the page unavailable to debug if a regression is
+      // introduced (and thus making debugging the regression harder).
+      AddSectionEntry(basic_info, "Auth Error Username",
+                      error_account_info ? error_account_info->email : "");
     } else {
       AddSectionEntry(basic_info, "Auth Error", "None");
     }
diff --git a/components/thread_pool_util/variations_util.cc b/components/thread_pool_util/variations_util.cc
index 09e66cc..f690e57e 100644
--- a/components/thread_pool_util/variations_util.cc
+++ b/components/thread_pool_util/variations_util.cc
@@ -62,8 +62,8 @@
   }
 
   auto params = std::make_unique<base::ThreadGroupParams>(
-      base::RecommendedMaxNumberOfThreadsInPool(min, max, cores_multiplier,
-                                                offset),
+      base::RecommendedMaxNumberOfThreadsInThreadGroup(
+          min, max, cores_multiplier, offset),
       base::TimeDelta::FromMilliseconds(detach_milliseconds));
 
   if (params->max_tasks() <= 0) {
diff --git a/components/viz/client/client_resource_provider_unittest.cc b/components/viz/client/client_resource_provider_unittest.cc
index b6511b76..896ca6c 100644
--- a/components/viz/client/client_resource_provider_unittest.cc
+++ b/components/viz/client/client_resource_provider_unittest.cc
@@ -489,8 +489,10 @@
       gpu::SHARED_IMAGE_USAGE_GLES2 | gpu::SHARED_IMAGE_USAGE_DISPLAY);
   gpu::SyncToken sync_token = sii->GenUnverifiedSyncToken();
 
+  constexpr gfx::Size size(64, 64);
   auto tran = TransferableResource::MakeGL(mailbox, GL_LINEAR, GL_TEXTURE_2D,
-                                           sync_token);
+                                           sync_token, size,
+                                           false /* is_overlay_candidate */);
   ResourceId resource = provider().ImportResource(
       tran, SingleReleaseCallback::Create(base::BindOnce(
                 &MockReleaseCallback::Released, base::Unretained(&release))));
diff --git a/components/viz/common/resources/transferable_resource.h b/components/viz/common/resources/transferable_resource.h
index d39240a..e6547e7 100644
--- a/components/viz/common/resources/transferable_resource.h
+++ b/components/viz/common/resources/transferable_resource.h
@@ -48,25 +48,15 @@
   static TransferableResource MakeGL(const gpu::Mailbox& mailbox,
                                      uint32_t filter,
                                      uint32_t texture_target,
-                                     const gpu::SyncToken& sync_token) {
+                                     const gpu::SyncToken& sync_token,
+                                     const gfx::Size& size,
+                                     bool is_overlay_candidate) {
     TransferableResource r;
     r.is_software = false;
     r.filter = filter;
     r.mailbox_holder.mailbox = mailbox;
     r.mailbox_holder.texture_target = texture_target;
     r.mailbox_holder.sync_token = sync_token;
-    r.size = gfx::Size();
-    return r;
-  }
-
-  static TransferableResource MakeGLOverlay(const gpu::Mailbox& mailbox,
-                                            uint32_t filter,
-                                            uint32_t texture_target,
-                                            const gpu::SyncToken& sync_token,
-                                            const gfx::Size& size,
-                                            bool is_overlay_candidate) {
-    TransferableResource r =
-        MakeGL(mailbox, filter, texture_target, sync_token);
     r.size = size;
     r.is_overlay_candidate = is_overlay_candidate;
     return r;
@@ -86,10 +76,7 @@
   // mailbox field is a gpu::Mailbox, else it is a SharedBitmapId.
   bool is_software = false;
 
-  // The number of pixels in the gpu mailbox/software bitmap. This must
-  // be set for software bitmaps, and must also be set for gpu mailboxes
-  // when they are an overlay candidate. Otherwise it will not be used
-  // and may be unset.
+  // The number of pixels in the gpu mailbox/software bitmap.
   gfx::Size size;
 
   // The format of the pixels in the gpu mailbox/software bitmap. This should
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index 6ad1ea5..beb6264 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -406,6 +406,7 @@
     "display_embedder/buffer_queue_unittest.cc",
     "display_embedder/server_shared_bitmap_manager_unittest.cc",
     "display_embedder/skia_output_surface_impl_unittest.cc",
+    "display_embedder/software_output_surface_unittest.cc",
     "display_embedder/vsync_parameter_listener_unittest.cc",
     "frame_sinks/compositor_frame_sink_support_unittest.cc",
     "frame_sinks/direct_layer_tree_frame_sink_unittest.cc",
diff --git a/components/viz/service/display/display_resource_provider_unittest.cc b/components/viz/service/display/display_resource_provider_unittest.cc
index 5fe0e27d..97c57a4ce 100644
--- a/components/viz/service/display/display_resource_provider_unittest.cc
+++ b/components/viz/service/display/display_resource_provider_unittest.cc
@@ -158,17 +158,18 @@
 
 
   TransferableResource CreateResource(ResourceFormat format) {
+    constexpr gfx::Size size(64, 64);
     if (use_gpu()) {
       gpu::Mailbox gpu_mailbox = gpu::Mailbox::Generate();
       gpu::SyncToken sync_token = GenSyncToken();
       EXPECT_TRUE(sync_token.HasData());
 
       TransferableResource gl_resource = TransferableResource::MakeGL(
-          gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token);
+          gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token, size,
+          false /* is_overlay_candidate */);
       gl_resource.format = format;
       return gl_resource;
     } else {
-      gfx::Size size(64, 64);
       SharedBitmapId shared_bitmap_id = CreateAndFillSharedBitmap(
           shared_bitmap_manager_.get(), size, format, 0);
 
@@ -186,8 +187,10 @@
     int child = resource_provider->CreateChild(return_callback, true);
 
     gpu::Mailbox gpu_mailbox = gpu::Mailbox::Generate();
-    auto resource = TransferableResource::MakeGL(gpu_mailbox, GL_LINEAR, target,
-                                                 sync_token);
+    constexpr gfx::Size size(64, 64);
+    auto resource =
+        TransferableResource::MakeGL(gpu_mailbox, GL_LINEAR, target, sync_token,
+                                     size, false /* is_overlay_candidate */);
     resource.id = 11;
     resource_provider->ReceiveFromChild(child, {resource});
     auto& map = resource_provider->GetChildToParentMap(child);
@@ -234,8 +237,10 @@
                              gpu::CommandBufferId::FromUnsafeValue(0x123),
                              0x42);
   auto mailbox = gpu::Mailbox::Generate();
+  constexpr gfx::Size size(64, 64);
   TransferableResource gl_resource = TransferableResource::MakeGL(
-      mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token1);
+      mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token1, size,
+      false /* is_overlay_candidate */);
   ResourceId id1 = child_resource_provider_->ImportResource(
       gl_resource, SingleReleaseCallback::Create(base::DoNothing()));
   std::vector<ReturnedResource> returned_to_child;
@@ -544,10 +549,11 @@
   gpu::Mailbox external_mailbox = gpu::Mailbox::Generate();
   gpu::SyncToken external_sync_token = GenSyncToken();
   EXPECT_TRUE(external_sync_token.HasData());
+  constexpr gfx::Size size(64, 64);
   ResourceId id = no_token_resource_provider->ImportResource(
       TransferableResource::MakeGL(external_mailbox, GL_LINEAR,
-                                   GL_TEXTURE_EXTERNAL_OES,
-                                   external_sync_token),
+                                   GL_TEXTURE_EXTERNAL_OES, external_sync_token,
+                                   size, false /* is_overlay_candidate */),
       SingleReleaseCallback::Create(base::DoNothing()));
 
   std::vector<ReturnedResource> returned_to_child;
@@ -822,8 +828,10 @@
 
     gpu::Mailbox gpu_mailbox = gpu::Mailbox::Generate();
     GLuint filter = mailbox_nearest_neighbor ? GL_NEAREST : GL_LINEAR;
-    auto resource = TransferableResource::MakeGL(gpu_mailbox, filter,
-                                                 GL_TEXTURE_2D, sync_token);
+    constexpr gfx::Size size(64, 64);
+    auto resource = TransferableResource::MakeGL(
+        gpu_mailbox, filter, GL_TEXTURE_2D, sync_token, size,
+        false /* is_overlay_candidate */);
 
     MockReleaseCallback release;
     ResourceId resource_id = child_resource_provider->ImportResource(
@@ -969,8 +977,10 @@
   std::unique_ptr<SingleReleaseCallback> callback =
       SingleReleaseCallback::Create(base::DoNothing());
 
+  constexpr gfx::Size size(64, 64);
   auto resource = TransferableResource::MakeGL(
-      gpu_mailbox, GL_LINEAR, GL_TEXTURE_EXTERNAL_OES, sync_token);
+      gpu_mailbox, GL_LINEAR, GL_TEXTURE_EXTERNAL_OES, sync_token, size,
+      false /* is_overlay_candidate */);
 
   ResourceId resource_id =
       child_resource_provider->ImportResource(resource, std::move(callback));
@@ -1081,7 +1091,7 @@
   gpu::SyncToken external_sync_token = GenSyncToken();
   EXPECT_TRUE(external_sync_token.HasData());
 
-  TransferableResource id1_transfer = TransferableResource::MakeGLOverlay(
+  TransferableResource id1_transfer = TransferableResource::MakeGL(
       external_mailbox, GL_LINEAR, GL_TEXTURE_EXTERNAL_OES, external_sync_token,
       gfx::Size(1, 1), true);
   id1_transfer.wants_promotion_hint = true;
@@ -1089,7 +1099,7 @@
   ResourceId id1 = child_resource_provider_->ImportResource(
       id1_transfer, SingleReleaseCallback::Create(base::DoNothing()));
 
-  TransferableResource id2_transfer = TransferableResource::MakeGLOverlay(
+  TransferableResource id2_transfer = TransferableResource::MakeGL(
       external_mailbox, GL_LINEAR, GL_TEXTURE_EXTERNAL_OES, external_sync_token,
       gfx::Size(1, 1), true);
   id2_transfer.wants_promotion_hint = false;
diff --git a/components/viz/service/display/display_scheduler.cc b/components/viz/service/display/display_scheduler.cc
index 830a74d..2ca07c9 100644
--- a/components/viz/service/display/display_scheduler.cc
+++ b/components/viz/service/display/display_scheduler.cc
@@ -332,7 +332,7 @@
   bool damaged = client_->SurfaceDamaged(surface_id, ack);
   ProcessSurfaceDamage(surface_id, ack, damaged);
 
-  return damaged;
+  return damaged && inside_begin_frame_deadline_interval_;
 }
 
 void DisplayScheduler::OnSurfaceDestroyed(const SurfaceId& surface_id) {
diff --git a/components/viz/service/display/display_scheduler_unittest.cc b/components/viz/service/display/display_scheduler_unittest.cc
index 365b88c..3e9de0b1 100644
--- a/components/viz/service/display/display_scheduler_unittest.cc
+++ b/components/viz/service/display/display_scheduler_unittest.cc
@@ -48,7 +48,7 @@
 
   bool SurfaceDamaged(const SurfaceId& surface_id,
                       const BeginFrameAck& ack) override {
-    return false;
+    return surface_damaged_return_value_;
   }
 
   void SurfaceDestroyed(const SurfaceId& surface_id) override {}
@@ -61,6 +61,10 @@
 
   void SetNextDrawAndSwapFails() { next_draw_and_swap_fails_ = true; }
 
+  void SetSurfaceDamagedReturnValue(bool surface_damaged_return_value) {
+    surface_damaged_return_value_ = surface_damaged_return_value;
+  }
+
   void SurfaceDamaged(const SurfaceId& surface_id) {
     undrawn_surfaces_.insert(surface_id);
   }
@@ -70,6 +74,7 @@
  protected:
   int draw_and_swap_count_;
   bool next_draw_and_swap_fails_;
+  bool surface_damaged_return_value_ = false;
   std::set<SurfaceId> undrawn_surfaces_;
   BeginFrameAck last_begin_frame_ack_;
 };
@@ -791,5 +796,35 @@
   EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
 }
 
+// This test verifies that if a client submits a frame after display scheduler's
+// deadline, it is acked immediately. https://crbug.com/951992
+TEST_F(DisplaySchedulerTest, AckImmediatelyAfterDeadline) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  BeginFrameAck ack;
+  ack.has_damage = true;
+
+  // Make the display always report that it is damaged in SurfaceDamaged.
+  client().SetSurfaceDamagedReturnValue(true);
+
+  scheduler_.SetNewRootSurface(root_surface_id);
+  scheduler_.SetVisible(true);
+
+  // Send a BeginFrame and pretend the client responded BEFORE the display
+  // scheduler deadline. OnSurfaceDamaged should return true, meaning that the
+  // ack should not be sent until display deadline.
+  AdvanceTimeAndBeginFrameForTest({root_surface_id});
+  EXPECT_TRUE(scheduler_.OnSurfaceDamaged(root_surface_id, ack));
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Send a BeginFrame and pretend the client responded AFTER the display
+  // scheduler deadline. OnSurfaceDamaged should return false, meaning that the
+  // ack should be sent immediately.
+  AdvanceTimeAndBeginFrameForTest({root_surface_id});
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_FALSE(scheduler_.OnSurfaceDamaged(root_surface_id, ack));
+}
+
 }  // namespace
 }  // namespace viz
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc
index b243a54..5be7e140 100644
--- a/components/viz/service/display/gl_renderer_unittest.cc
+++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -698,7 +698,7 @@
 
   // Here is where the texture is created. Any value bigger than 1024 should use
   // a highp.
-  auto transfer_resource = TransferableResource::MakeGLOverlay(
+  auto transfer_resource = TransferableResource::MakeGL(
       gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
       gfx::Size(1025, 1025), true);
   ResourceId client_resource_id = child_resource_provider->ImportResource(
@@ -761,7 +761,7 @@
 
   // Here is where the texture is created. Any value smaller than 1024 should
   // use a mediump.
-  auto transfer_resource = TransferableResource::MakeGLOverlay(
+  auto transfer_resource = TransferableResource::MakeGL(
       gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
       gfx::Size(1023, 1023), true);
   ResourceId client_resource_id = child_resource_provider->ImportResource(
@@ -1776,7 +1776,8 @@
   RenderPass* root_pass;
 
   auto transfer_resource = TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+      child_rect.size(), false /* is_overlay_candidate */);
   ResourceId mask = child_resource_provider_->ImportResource(
       transfer_resource, SingleReleaseCallback::Create(base::DoNothing()));
 
@@ -2232,7 +2233,7 @@
   child_context_provider->BindToCurrentThread();
   auto child_resource_provider = std::make_unique<ClientResourceProvider>(true);
 
-  auto transfer_resource = TransferableResource::MakeGLOverlay(
+  auto transfer_resource = TransferableResource::MakeGL(
       gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
       gfx::Size(256, 256), true);
   auto release_callback =
@@ -2446,7 +2447,7 @@
 
   gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
                             gpu::CommandBufferId::FromUnsafeValue(0x123), 29);
-  auto transfer_resource = TransferableResource::MakeGLOverlay(
+  auto transfer_resource = TransferableResource::MakeGL(
       gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, sync_token,
       gfx::Size(256, 256), true);
   auto release_callback =
@@ -2835,7 +2836,7 @@
   child_context_provider->BindToCurrentThread();
   auto child_resource_provider = std::make_unique<ClientResourceProvider>(true);
 
-  auto transfer_resource = TransferableResource::MakeGLOverlay(
+  auto transfer_resource = TransferableResource::MakeGL(
       gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
       gfx::Size(256, 256), true);
   auto release_callback =
@@ -4109,7 +4110,7 @@
     child_context_provider_->BindToCurrentThread();
 
     child_resource_provider_ = std::make_unique<ClientResourceProvider>(true);
-    auto transfer_resource = TransferableResource::MakeGLOverlay(
+    auto transfer_resource = TransferableResource::MakeGL(
         gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
         gfx::Size(256, 256), true);
     ResourceId client_resource_id = child_resource_provider_->ImportResource(
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc
index 0923324..2b07fa8a 100644
--- a/components/viz/service/display/overlay_unittest.cc
+++ b/components/viz/service/display/overlay_unittest.cc
@@ -278,7 +278,7 @@
     ClientResourceProvider* child_resource_provider,
     const gfx::Size& size,
     bool is_overlay_candidate) {
-  auto resource = TransferableResource::MakeGLOverlay(
+  auto resource = TransferableResource::MakeGL(
       gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
       size, is_overlay_candidate);
   auto release_callback = SingleReleaseCallback::Create(
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc
index a855b21..35b28738 100644
--- a/components/viz/service/display/renderer_pixeltest.cc
+++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -99,8 +99,8 @@
   gpu::SyncToken sync_token = sii->GenUnverifiedSyncToken();
 
   TransferableResource gl_resource = TransferableResource::MakeGL(
-      mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token);
-  gl_resource.size = size;
+      mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token, size,
+      false /* is_overlay_candidate */);
   gl_resource.format = format;
   gl_resource.color_space = std::move(color_space);
   auto release_callback = SingleReleaseCallback::Create(
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
index bfa96e06..aa31956 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -832,7 +832,13 @@
         continue;
       }
 
-      DCHECK(representation->size() == context->size);
+      if (representation->size() != context->size) {
+        DLOG(ERROR) << "Failed to fulfill the promise texture - SharedImage "
+                       "size does not match TransferableResource size.";
+        CreateFallbackImage(context);
+        continue;
+      }
+
       context->representation = std::move(representation);
       context->promise_image_texture = context->representation->BeginReadAccess(
           begin_semaphores, end_semaphores);
@@ -856,7 +862,7 @@
       // (GLES2Interface).
       DLOG(ERROR)
           << "Failed to fulfill the promise texture whose backend is not "
-             "compitable with vulkan.";
+             "compatible with vulkan.";
       CreateFallbackImage(context);
       continue;
     }
@@ -867,7 +873,16 @@
       CreateFallbackImage(context);
       continue;
     }
-    BindOrCopyTextureIfNecessary(texture_base);
+
+    gfx::Size texture_size;
+    if (BindOrCopyTextureIfNecessary(texture_base, &texture_size) &&
+        texture_size != context->size) {
+      DLOG(ERROR) << "Failed to fulfill the promise texture - texture "
+                     "size does not match TransferableResource size.";
+      CreateFallbackImage(context);
+      continue;
+    }
+
     GrBackendTexture backend_texture;
     gpu::GetGrBackendTexture(gl_version_info_, texture_base->target(),
                              context->size, texture_base->service_id(),
@@ -991,11 +1006,12 @@
 #endif
 }
 
-void SkiaOutputSurfaceImplOnGpu::BindOrCopyTextureIfNecessary(
-    gpu::TextureBase* texture_base) {
+bool SkiaOutputSurfaceImplOnGpu::BindOrCopyTextureIfNecessary(
+    gpu::TextureBase* texture_base,
+    gfx::Size* size) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (texture_base->GetType() != gpu::TextureBase::Type::kValidated)
-    return;
+    return false;
   // If a texture is validated and bound to an image, we may defer copying the
   // image to the texture until the texture is used. It is for implementing low
   // latency drawing (e.g. fast ink) and avoiding unnecessary texture copy. So
@@ -1007,15 +1023,24 @@
   if (image && image_state == gpu::gles2::Texture::UNBOUND) {
     glBindTexture(texture_base->target(), texture_base->service_id());
     if (image->ShouldBindOrCopy() == gl::GLImage::BIND) {
-      if (!image->BindTexImage(texture_base->target()))
+      if (!image->BindTexImage(texture_base->target())) {
         LOG(ERROR) << "Failed to bind a gl image to texture.";
+        return false;
+      }
     } else {
       texture->SetLevelImageState(texture_base->target(), 0,
                                   gpu::gles2::Texture::COPIED);
-      if (!image->CopyTexImage(texture_base->target()))
+      if (!image->CopyTexImage(texture_base->target())) {
         LOG(ERROR) << "Failed to copy a gl image to texture.";
+        return false;
+      }
     }
   }
+  GLsizei temp_width, temp_height;
+  texture->GetLevelSize(texture_base->target(), 0 /* level */, &temp_width,
+                        &temp_height, nullptr /* depth */);
+  *size = gfx::Size(temp_width, temp_height);
+  return true;
 }
 
 bool SkiaOutputSurfaceImplOnGpu::MakeCurrent(bool need_fbo0) {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index 656e218..5c1c03c 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -163,7 +163,11 @@
   void InitializeForGLWithGpuService(GpuServiceImpl* gpu_service);
   void InitializeForVulkan(GpuServiceImpl* gpu_service);
 
-  void BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base);
+  // Returns true if |texture_base| is a gles2::Texture and all necessary
+  // operations completed successfully. In this case, |*size| is the size of
+  // of level 0.
+  bool BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base,
+                                    gfx::Size* size);
 
   // Make context current for GL, and return false if the context is lost.
   // It will do nothing when Vulkan is used.
diff --git a/components/viz/service/display_embedder/software_output_surface_unittest.cc b/components/viz/service/display_embedder/software_output_surface_unittest.cc
new file mode 100644
index 0000000..d83f1f3
--- /dev/null
+++ b/components/viz/service/display_embedder/software_output_surface_unittest.cc
@@ -0,0 +1,103 @@
+// 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/software_output_surface.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/test/bind_test_util.h"
+#include "cc/test/fake_output_surface_client.h"
+#include "components/viz/service/display/output_surface_frame.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/vsync_provider.h"
+
+namespace viz {
+namespace {
+
+class FakeVSyncProvider : public gfx::VSyncProvider {
+ public:
+  FakeVSyncProvider() = default;
+  ~FakeVSyncProvider() override = default;
+
+  int call_count() const { return call_count_; }
+
+  // gfx::VSyncProvider implementation.
+  void GetVSyncParameters(UpdateVSyncCallback callback) override {
+    std::move(callback).Run(base::TimeTicks(), base::TimeDelta());
+    call_count_++;
+  }
+
+  bool GetVSyncParametersIfAvailable(base::TimeTicks* timebase,
+                                     base::TimeDelta* interval) override {
+    return false;
+  }
+
+  bool SupportGetVSyncParametersIfAvailable() const override { return false; }
+  bool IsHWClock() const override { return false; }
+
+ private:
+  int call_count_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeVSyncProvider);
+};
+
+class VSyncSoftwareOutputDevice : public SoftwareOutputDevice {
+ public:
+  VSyncSoftwareOutputDevice() = default;
+  ~VSyncSoftwareOutputDevice() override = default;
+
+  // SoftwareOutputDevice implementation.
+  gfx::VSyncProvider* GetVSyncProvider() override { return &vsync_provider_; }
+
+ private:
+  FakeVSyncProvider vsync_provider_;
+
+  DISALLOW_COPY_AND_ASSIGN(VSyncSoftwareOutputDevice);
+};
+
+}  // namespace
+
+TEST(SoftwareOutputSurfaceTest, NoVSyncProvider) {
+  auto output_surface = std::make_unique<SoftwareOutputSurface>(
+      std::make_unique<SoftwareOutputDevice>());
+  cc::FakeOutputSurfaceClient output_surface_client;
+  output_surface->BindToClient(&output_surface_client);
+
+  // Verify the callback is never called.
+  output_surface->SetUpdateVSyncParametersCallback(base::BindRepeating(
+      [](base::TimeTicks timebase, base::TimeDelta interval) {
+        EXPECT_TRUE(false);
+      }));
+
+  output_surface->SwapBuffers(OutputSurfaceFrame());
+  EXPECT_EQ(nullptr, output_surface->software_device()->GetVSyncProvider());
+}
+
+TEST(SoftwareOutputSurfaceTest, VSyncProviderUpdates) {
+  auto output_surface = std::make_unique<SoftwareOutputSurface>(
+      std::make_unique<VSyncSoftwareOutputDevice>());
+  cc::FakeOutputSurfaceClient output_surface_client;
+  output_surface->BindToClient(&output_surface_client);
+
+  int update_vsync_parameters_call_count = 0;
+  output_surface->SetUpdateVSyncParametersCallback(base::BindLambdaForTesting(
+      [&update_vsync_parameters_call_count](base::TimeTicks timebase,
+                                            base::TimeDelta interval) {
+        ++update_vsync_parameters_call_count;
+      }));
+
+  FakeVSyncProvider* vsync_provider = static_cast<FakeVSyncProvider*>(
+      output_surface->software_device()->GetVSyncProvider());
+  EXPECT_EQ(0, vsync_provider->call_count());
+
+  // Verify that we get vsync parameters from the VSyncProvider and provide them
+  // to the callback.
+  output_surface->SwapBuffers(OutputSurfaceFrame());
+  EXPECT_EQ(1, vsync_provider->call_count());
+  EXPECT_EQ(1, update_vsync_parameters_call_count);
+}
+
+}  // namespace viz
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc
index e68b3a2..10e6689 100644
--- a/components/viz/test/test_layer_tree_frame_sink.cc
+++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -148,6 +148,7 @@
   frame_sink_manager_ = nullptr;
   shared_bitmap_manager_ = nullptr;
   test_client_ = nullptr;
+  weak_ptr_factory_.InvalidateWeakPtrs();
   LayerTreeFrameSink::DetachFromClient();
 }
 
@@ -222,7 +223,11 @@
   // used.
   if (!display_->has_scheduler())
     return;
-  client_->DidReceiveCompositorFrameAck();
+  // Do a PostTask, because the cc::Scheduler doesn't like a synchronous ack.
+  compositor_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&TestLayerTreeFrameSink::SendCompositorFrameAckToClient,
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 void TestLayerTreeFrameSink::OnBeginFrame(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 644fdab..e4d58d41 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -329,8 +329,6 @@
     "after_startup_task_utils.h",
     "android/android_overlay_provider_impl.cc",
     "android/android_overlay_provider_impl.h",
-    "android/android_ui_constants.cc",
-    "android/android_ui_constants.h",
     "android/app_web_message_port.cc",
     "android/app_web_message_port.h",
     "android/background_sync_network_observer_android.cc",
diff --git a/content/browser/accessibility/accessibility_event_recorder_auralinux.cc b/content/browser/accessibility/accessibility_event_recorder_auralinux.cc
index 24c83f29..31cd773 100644
--- a/content/browser/accessibility/accessibility_event_recorder_auralinux.cc
+++ b/content/browser/accessibility/accessibility_event_recorder_auralinux.cc
@@ -51,6 +51,7 @@
  private:
   bool ShouldUseATSPI();
 
+  std::string AtkObjectToString(AtkObject* obj, bool include_name);
   void AddATKEventListener(const char* event_name);
   void AddATKEventListeners();
   void RemoveATKEventListeners();
@@ -152,6 +153,7 @@
   AddATKEventListener("ATK:AtkObject:state-change");
   AddATKEventListener("ATK:AtkObject:focus-event");
   AddATKEventListener("ATK:AtkObject:property-change");
+  AddATKEventListener("ATK:AtkObject:children-changed");
   AddATKEventListener("ATK:AtkText:text-insert");
   AddATKEventListener("ATK:AtkText:text-remove");
   AddATKEventListener("ATK:AtkSelection:selection-changed");
@@ -182,6 +184,20 @@
   }
 }
 
+std::string AccessibilityEventRecorderAuraLinux::AtkObjectToString(
+    AtkObject* obj,
+    bool include_name) {
+  std::string role = atk_role_get_name(atk_object_get_role(obj));
+  base::ReplaceChars(role, " ", "_", &role);
+  std::string str =
+      base::StringPrintf("role=ROLE_%s", base::ToUpperASCII(role).c_str());
+  // Getting the name breaks firing of name-change events. Allow disabling of
+  // logging the name in those situations.
+  if (include_name)
+    str += base::StringPrintf(" name='%s'", atk_object_get_name(obj));
+  return str;
+}
+
 void AccessibilityEventRecorderAuraLinux::ProcessATKEvent(
     const char* event,
     unsigned int n_params,
@@ -192,6 +208,7 @@
     return;
   }
 
+  bool log_name = true;
   std::string event_name(event);
   std::string log;
   if (event_name.find("property-change") != std::string::npos) {
@@ -214,6 +231,17 @@
     } else {
       return;
     }
+  } else if (event_name.find("children-changed") != std::string::npos) {
+    log_name = false;
+    log += base::ToUpperASCII(event);
+    // Despite this actually being a signed integer, it's defined as a uint.
+    int index = static_cast<int>(g_value_get_uint(&params[1]));
+    log += base::StringPrintf(" index:%d", index);
+    AtkObject* child = static_cast<AtkObject*>(g_value_get_pointer(&params[2]));
+    if (child)
+      log += " CHILD:(" + AtkObjectToString(child, log_name) + ")";
+    else
+      log += " CHILD:(NULL)";
   } else {
     log += base::ToUpperASCII(event);
     if (event_name.find("state-change") != std::string::npos) {
@@ -234,10 +262,7 @@
   }
 
   AtkObject* obj = ATK_OBJECT(g_value_get_object(&params[0]));
-  std::string role = atk_role_get_name(atk_object_get_role(obj));
-  base::ReplaceChars(role, " ", "_", &role);
-  log += base::StringPrintf(" role=ROLE_%s", base::ToUpperASCII(role).c_str());
-  log += base::StringPrintf(" name='%s'", atk_object_get_name(obj));
+  log += " " + AtkObjectToString(obj, log_name);
 
   std::string states = "";
   AtkStateSet* state_set = atk_object_ref_state_set(obj);
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
index 253c7db..27db75b 100644
--- a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -119,6 +119,13 @@
   ToBrowserAccessibilityAuraLinux(node)->GetNode()->OnDescriptionChanged();
 }
 
+void BrowserAccessibilityManagerAuraLinux::FireSubtreeCreatedEvent(
+    BrowserAccessibility* node) {
+  // Sending events during a load would create a lot of spam, don't do that.
+  if (GetTreeData().loaded)
+    ToBrowserAccessibilityAuraLinux(node)->GetNode()->OnSubtreeCreated();
+}
+
 void BrowserAccessibilityManagerAuraLinux::FireGeneratedEvent(
     ui::AXEventGenerator::Event event_type,
     BrowserAccessibility* node) {
@@ -158,6 +165,9 @@
     case ui::AXEventGenerator::Event::SELECTED_CHANGED:
       FireSelectedEvent(node);
       break;
+    case ui::AXEventGenerator::Event::SUBTREE_CREATED:
+      FireSubtreeCreatedEvent(node);
+      break;
     case ui::AXEventGenerator::Event::VALUE_CHANGED:
       FireEvent(node, ax::mojom::Event::kValueChanged);
       break;
@@ -209,6 +219,19 @@
   document_platform_node->SetEmbeddingWindow(window);
 }
 
+void BrowserAccessibilityManagerAuraLinux::OnSubtreeWillBeDeleted(
+    ui::AXTree* tree,
+    ui::AXNode* node) {
+  BrowserAccessibilityManager::OnSubtreeWillBeDeleted(tree, node);
+  // Sending events on load/destruction would create a lot of spam, avoid that.
+  if (!GetTreeData().loaded)
+    return;
+
+  BrowserAccessibility* obj = GetFromAXNode(node);
+  if (obj && obj->IsNative())
+    ToBrowserAccessibilityAuraLinux(obj)->GetNode()->OnSubtreeWillBeDeleted();
+}
+
 void BrowserAccessibilityManagerAuraLinux::OnAtomicUpdateFinished(
     ui::AXTree* tree,
     bool root_changed,
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.h b/content/browser/accessibility/browser_accessibility_manager_auralinux.h
index 9019341..18e932f 100644
--- a/content/browser/accessibility/browser_accessibility_manager_auralinux.h
+++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.h
@@ -38,9 +38,11 @@
   void FireLoadingEvent(BrowserAccessibility* node, bool is_loading);
   void FireNameChangedEvent(BrowserAccessibility* node);
   void FireDescriptionChangedEvent(BrowserAccessibility* node);
+  void FireSubtreeCreatedEvent(BrowserAccessibility* node);
 
  protected:
   // AXTreeObserver methods.
+  void OnSubtreeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
   void OnAtomicUpdateFinished(
       ui::AXTree* tree,
       bool root_changed,
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index b2cda9995..1aee10d8 100644
--- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -323,6 +323,11 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
+                       AccessibilityEventsAddChild) {
+  RunEventTest(FILE_PATH_LITERAL("add-child.html"));
+}
+
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
                        AccessibilityEventsAddChildOfBody) {
   RunEventTest(FILE_PATH_LITERAL("add-child-of-body.html"));
 }
diff --git a/content/browser/android/android_ui_constants.cc b/content/browser/android/android_ui_constants.cc
deleted file mode 100644
index f62c87d..0000000
--- a/content/browser/android/android_ui_constants.cc
+++ /dev/null
@@ -1,27 +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 "content/browser/android/android_ui_constants.h"
-
-#include "base/android/jni_android.h"
-#include "jni/UiConstants_jni.h"
-
-bool AndroidUiConstants::IsFocusRingOutset() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  return Java_UiConstants_isFocusRingOutset(env);
-}
-
-base::Optional<float> AndroidUiConstants::GetMinimumStrokeWidthForFocusRing() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  if (!Java_UiConstants_hasCustomMinimumStrokeWidthForFocusRing(env))
-    return base::nullopt;
-  return Java_UiConstants_getMinimumStrokeWidthForFocusRing(env);
-}
-
-base::Optional<SkColor> AndroidUiConstants::GetFocusRingColor() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  if (!Java_UiConstants_hasCustomFocusRingColor(env))
-    return base::nullopt;
-  return Java_UiConstants_getFocusRingColor(env);
-}
diff --git a/content/browser/android/android_ui_constants.h b/content/browser/android/android_ui_constants.h
deleted file mode 100644
index 735f67a..0000000
--- a/content/browser/android/android_ui_constants.h
+++ /dev/null
@@ -1,22 +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 CONTENT_BROWSER_ANDROID_ANDROID_UI_CONSTANTS_H_
-#define CONTENT_BROWSER_ANDROID_ANDROID_UI_CONSTANTS_H_
-
-#include "base/macros.h"
-#include "base/optional.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-class AndroidUiConstants {
- public:
-  static bool IsFocusRingOutset();
-  static base::Optional<float> GetMinimumStrokeWidthForFocusRing();
-  static base::Optional<SkColor> GetFocusRingColor();
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(AndroidUiConstants);
-};
-
-#endif  // CONTENT_BROWSER_ANDROID_ANDROID_UI_CONSTANTS_H_
diff --git a/content/browser/background_fetch/background_fetch_event_dispatcher.cc b/content/browser/background_fetch/background_fetch_event_dispatcher.cc
index c08f3a54..f41de4e 100644
--- a/content/browser/background_fetch/background_fetch_event_dispatcher.cc
+++ b/content/browser/background_fetch/background_fetch_event_dispatcher.cc
@@ -342,17 +342,17 @@
     return;
 
   std::map<std::string, std::string> metadata = {
-      {"event type", EventTypeToString(event_type)}};
+      {"Event Type", EventTypeToString(event_type)}};
   if (failure_reason != blink::mojom::BackgroundFetchFailureReason::NONE) {
     std::stringstream stream;
     stream << failure_reason;
-    metadata["failure reason"] = stream.str();
+    metadata["Failure Reason"] = stream.str();
   }
 
   devtools_context_->LogBackgroundServiceEvent(
       registration_id.service_worker_registration_id(),
       registration_id.origin(), devtools::proto::BACKGROUND_FETCH,
-      /* event_name= */ "background fetch completed",
+      /* event_name= */ "Background Fetch completed",
       /* instance_id= */ registration_id.developer_id(), metadata);
 }
 
diff --git a/content/browser/background_fetch/background_fetch_scheduler.cc b/content/browser/background_fetch/background_fetch_scheduler.cc
index 8334eaa..0b8e44c 100644
--- a/content/browser/background_fetch/background_fetch_scheduler.cc
+++ b/content/browser/background_fetch/background_fetch_scheduler.cc
@@ -351,8 +351,8 @@
   LogBackgroundFetchEventForDevTools(
       Event::kFetchRegistered, registration_id,
       /* request_info= */ nullptr,
-      {{"total requests", base::NumberToString(num_requests)},
-       {"start paused", start_paused ? "yes" : "no"}});
+      {{"Total Requests", base::NumberToString(num_requests)},
+       {"Start Paused", start_paused ? "Yes" : "No"}});
 
   registration_notifier_->NoteTotalRequests(registration_id.unique_id(),
                                             num_requests);
@@ -387,8 +387,8 @@
   LogBackgroundFetchEventForDevTools(
       Event::kFetchResumedOnStartup, registration_id,
       /* request_info= */ nullptr,
-      {{"completed requests", base::NumberToString(num_completed_requests)},
-       {"active requests",
+      {{"Completed Requests", base::NumberToString(num_completed_requests)},
+       {"Active Requests",
         base::NumberToString(active_fetch_requests.size())}});
 
   auto controller = CreateInitializedController(
@@ -522,24 +522,24 @@
   // any additional data to |metadata|.
   switch (event) {
     case Event::kFetchRegistered:
-      event_name = "background fetch registered";
+      event_name = "Background Fetch registered";
       break;
     case Event::kFetchResumedOnStartup:
-      event_name = "background fetch resuming after browser restart";
+      event_name = "Background Fetch resuming after browser restart";
       break;
     case Event::kFetchScheduled:
-      event_name = "background fetch started";
+      event_name = "Background Fetch started";
       break;
     case Event::kRequestStarted:
-      event_name = "request processing started";
+      event_name = "Request processing started";
       DCHECK(request_info);
       break;
     case Event::kRequestCompleted:
-      event_name = "request processing completed";
+      event_name = "Request processing completed";
       DCHECK(request_info);
-      metadata["response status"] =
+      metadata["Response Status"] =
           base::NumberToString(request_info->GetResponseCode());
-      metadata["response size (bytes)"] =
+      metadata["Response Size (bytes)"] =
           base::NumberToString(request_info->GetResponseSize());
       break;
   }
@@ -548,11 +548,11 @@
 
   // Include common request metadata.
   if (request_info) {
-    metadata["url"] = request_info->fetch_request()->url.spec();
-    metadata["request index"] =
+    metadata["URL"] = request_info->fetch_request()->url.spec();
+    metadata["Request Index"] =
         base::NumberToString(request_info->request_index());
     if (request_info->request_body_size())
-      metadata["upload size (bytes)"] =
+      metadata["Upload Size (bytes)"] =
           base::NumberToString(request_info->request_body_size());
   }
 
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index 64723b1..200a37a 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -964,7 +964,7 @@
   if (ShouldLogToDevTools(sync_type)) {
     devtools_context_->LogBackgroundServiceEvent(
         sw_registration_id, origin, devtools::proto::BACKGROUND_SYNC,
-        /* event_name= */ "registered sync",
+        /* event_name= */ "Registered sync",
         /* instance_id= */ sync_registration.options()->tag,
         /* event_metadata= */ {});
   }
@@ -1028,10 +1028,10 @@
     devtools_context_->LogBackgroundServiceEvent(
         active_version->registration_id(), active_version->script_origin(),
         devtools::proto::BACKGROUND_SYNC,
-        /* event_name= */ "dispatched sync event",
+        /* event_name= */ "Dispatched sync event",
         /* instance_id= */ tag,
         /* event_metadata= */
-        {{"last chance", last_chance ? "yes" : "no"}});
+        {{"Last Chance", last_chance ? "Yes" : "No"}});
   }
 }
 
@@ -1459,7 +1459,7 @@
       devtools_context_->LogBackgroundServiceEvent(
           registration_info->service_worker_registration_id, origin,
           devtools::proto::BACKGROUND_SYNC,
-          /* event_name= */ "sync event reregistered",
+          /* event_name= */ "Sync event reregistered",
           /* instance_id= */ registration_info->tag,
           /* event_metadata= */ {});
     }
@@ -1476,10 +1476,10 @@
       devtools_context_->LogBackgroundServiceEvent(
           registration_info->service_worker_registration_id, origin,
           devtools::proto::BACKGROUND_SYNC,
-          /* event_name= */ "sync event failed",
+          /* event_name= */ "Sync event failed",
           /* instance_id= */ registration_info->tag,
-          {{"next attempt delay (ms)", delay_ms},
-           {"failure reason", GetEventStatusString(status_code)}});
+          {{"Next Attempt Delay (ms)", delay_ms},
+           {"Failure Reason", GetEventStatusString(status_code)}});
     }
   }
 
@@ -1491,9 +1491,9 @@
       devtools_context_->LogBackgroundServiceEvent(
           registration_info->service_worker_registration_id, origin,
           devtools::proto::BACKGROUND_SYNC,
-          /* event_name= */ "sync complete",
+          /* event_name= */ "Sync completed",
           /* instance_id= */ registration_info->tag,
-          {{"status", GetEventStatusString(status_code)}});
+          {{"Status", GetEventStatusString(status_code)}});
     }
 
     if (registration_info->sync_type ==
diff --git a/content/browser/compositor/reflector_impl.cc b/content/browser/compositor/reflector_impl.cc
index b41cb5b..873f229 100644
--- a/content/browser/compositor/reflector_impl.cc
+++ b/content/browser/compositor/reflector_impl.cc
@@ -151,9 +151,10 @@
                                   const gfx::Rect& redraw_rect) {
   if (layer_data->needs_set_mailbox) {
     layer_data->layer->SetTransferableResource(
-        viz::TransferableResource::MakeGL(mailbox_->holder().mailbox, GL_LINEAR,
-                                          mailbox_->holder().texture_target,
-                                          mailbox_->holder().sync_token),
+        viz::TransferableResource::MakeGL(
+            mailbox_->holder().mailbox, GL_LINEAR,
+            mailbox_->holder().texture_target, mailbox_->holder().sync_token,
+            source_size, false /* is_overlay_candidate */),
         mailbox_->GetSingleReleaseCallback(), source_size);
     layer_data->needs_set_mailbox = false;
   } else {
diff --git a/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc b/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
deleted file mode 100644
index 7db8031..0000000
--- a/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
+++ /dev/null
@@ -1,169 +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 "content/browser/compositor/software_browser_compositor_output_surface.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/test/test_message_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "components/viz/common/frame_sinks/begin_frame_source.h"
-#include "components/viz/common/frame_sinks/delay_based_time_source.h"
-#include "components/viz/service/display/output_surface_frame.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/compositor/compositor.h"
-#include "ui/compositor/test/test_context_factories.h"
-#include "ui/gfx/vsync_provider.h"
-
-namespace {
-
-class FakeVSyncProvider : public gfx::VSyncProvider {
- public:
-  FakeVSyncProvider() : call_count_(0) {}
-  ~FakeVSyncProvider() override {}
-
-  void GetVSyncParameters(UpdateVSyncCallback callback) override {
-    std::move(callback).Run(timebase_, interval_);
-    call_count_++;
-  }
-
-  bool GetVSyncParametersIfAvailable(base::TimeTicks* timebase,
-                                     base::TimeDelta* interval) override {
-    return false;
-  }
-
-  bool SupportGetVSyncParametersIfAvailable() const override { return false; }
-  bool IsHWClock() const override { return false; }
-
-  int call_count() const { return call_count_; }
-
-  void set_timebase(base::TimeTicks timebase) { timebase_ = timebase; }
-  void set_interval(base::TimeDelta interval) { interval_ = interval; }
-
- private:
-  base::TimeTicks timebase_;
-  base::TimeDelta interval_;
-
-  int call_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeVSyncProvider);
-};
-
-class FakeSoftwareOutputDevice : public viz::SoftwareOutputDevice {
- public:
-  FakeSoftwareOutputDevice() : vsync_provider_(new FakeVSyncProvider()) {}
-  ~FakeSoftwareOutputDevice() override {}
-
-  gfx::VSyncProvider* GetVSyncProvider() override {
-    return vsync_provider_.get();
-  }
-
- private:
-  std::unique_ptr<gfx::VSyncProvider> vsync_provider_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeSoftwareOutputDevice);
-};
-
-}  // namespace
-
-class SoftwareBrowserCompositorOutputSurfaceTest : public testing::Test {
- public:
-  SoftwareBrowserCompositorOutputSurfaceTest()
-      : begin_frame_source_(std::make_unique<viz::DelayBasedTimeSource>(
-                                message_loop_.task_runner().get()),
-                            viz::BeginFrameSource::kNotRestartableId) {}
-  ~SoftwareBrowserCompositorOutputSurfaceTest() override = default;
-
-  void SetUp() override;
-  void TearDown() override;
-
-  void UpdateVSyncParameters(base::TimeTicks timebase,
-                             base::TimeDelta interval);
-
-  std::unique_ptr<content::BrowserCompositorOutputSurface> CreateSurface(
-      std::unique_ptr<viz::SoftwareOutputDevice> device);
-
- protected:
-  std::unique_ptr<content::BrowserCompositorOutputSurface> output_surface_;
-
-  // TODO(crbug.com/616973): We shouldn't be using ThreadTaskRunnerHandle::Get()
-  // inside the OutputSurface, so we shouldn't need a MessageLoop. The
-  // OutputSurface should be using the TaskRunner given to the compositor.
-  base::TestMessageLoop message_loop_;
-  viz::DelayBasedBeginFrameSource begin_frame_source_;
-  std::unique_ptr<ui::TestContextFactories> context_factories_;
-  std::unique_ptr<ui::Compositor> compositor_;
-  int update_vsync_parameters_call_count_ = 0;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SoftwareBrowserCompositorOutputSurfaceTest);
-};
-
-void SoftwareBrowserCompositorOutputSurfaceTest::SetUp() {
-  const bool enable_pixel_output = false;
-  context_factories_ =
-      std::make_unique<ui::TestContextFactories>(enable_pixel_output);
-
-  compositor_ = std::make_unique<ui::Compositor>(
-      context_factories_->GetContextFactoryPrivate()->AllocateFrameSinkId(),
-      context_factories_->GetContextFactory(),
-      context_factories_->GetContextFactoryPrivate(),
-      message_loop_.task_runner().get(), false /* enable_pixel_canvas */);
-  compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
-}
-
-void SoftwareBrowserCompositorOutputSurfaceTest::TearDown() {
-  output_surface_.reset();
-  compositor_.reset();
-  context_factories_.reset();
-}
-
-std::unique_ptr<content::BrowserCompositorOutputSurface>
-SoftwareBrowserCompositorOutputSurfaceTest::CreateSurface(
-    std::unique_ptr<viz::SoftwareOutputDevice> device) {
-  auto surface =
-      std::make_unique<content::SoftwareBrowserCompositorOutputSurface>(
-          std::move(device));
-  surface->SetUpdateVSyncParametersCallback(base::BindRepeating(
-      &SoftwareBrowserCompositorOutputSurfaceTest::UpdateVSyncParameters,
-      base::Unretained(this)));
-  return surface;
-}
-
-void SoftwareBrowserCompositorOutputSurfaceTest::UpdateVSyncParameters(
-    base::TimeTicks timebase,
-    base::TimeDelta interval) {
-  update_vsync_parameters_call_count_++;
-}
-
-TEST_F(SoftwareBrowserCompositorOutputSurfaceTest, NoVSyncProvider) {
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<viz::SoftwareOutputDevice> software_device(
-      new viz::SoftwareOutputDevice());
-  output_surface_ = CreateSurface(std::move(software_device));
-  output_surface_->BindToClient(&output_surface_client);
-
-  output_surface_->SwapBuffers(viz::OutputSurfaceFrame());
-  EXPECT_EQ(nullptr, output_surface_->software_device()->GetVSyncProvider());
-  EXPECT_EQ(0, update_vsync_parameters_call_count_);
-}
-
-TEST_F(SoftwareBrowserCompositorOutputSurfaceTest, VSyncProviderUpdates) {
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<viz::SoftwareOutputDevice> software_device(
-      new FakeSoftwareOutputDevice());
-  output_surface_ = CreateSurface(std::move(software_device));
-  output_surface_->BindToClient(&output_surface_client);
-
-  FakeVSyncProvider* vsync_provider = static_cast<FakeVSyncProvider*>(
-      output_surface_->software_device()->GetVSyncProvider());
-  EXPECT_EQ(0, vsync_provider->call_count());
-
-  output_surface_->SwapBuffers(viz::OutputSurfaceFrame());
-  EXPECT_EQ(1, vsync_provider->call_count());
-  EXPECT_EQ(1, update_vsync_parameters_call_count_);
-}
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 02d54e7..9d34dc1 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -81,6 +81,7 @@
 #include "services/metrics/public/cpp/ukm_source_id.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
+#include "services/service_manager/public/cpp/connector.h"
 #include "storage/browser/blob/blob_url_loader_factory.h"
 #include "storage/browser/blob/blob_url_request_job_factory.h"
 #include "url/origin.h"
@@ -672,6 +673,23 @@
                            : nullptr;
 }
 
+std::unique_ptr<service_manager::Connector>
+DownloadManagerImpl::GetServiceConnector() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  service_manager::Connector* connector = GetServiceManagerConnector();
+  if (connector)
+    return connector->Clone();  // Clone for use on a different thread.
+  return nullptr;
+}
+
+service_manager::Connector* DownloadManagerImpl::GetServiceManagerConnector() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (auto* connection = ServiceManagerConnection::GetForProcess())
+    return connection->GetConnector();
+  return nullptr;
+}
+
 void DownloadManagerImpl::StartDownload(
     std::unique_ptr<download::DownloadCreateInfo> info,
     std::unique_ptr<download::InputStream> stream,
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h
index b6859f1..f2dd1e4 100644
--- a/content/browser/download/download_manager_impl.h
+++ b/content/browser/download/download_manager_impl.h
@@ -207,6 +207,7 @@
       override;
   net::URLRequestContextGetter* GetURLRequestContextGetter(
       const download::DownloadCreateInfo& info) override;
+  std::unique_ptr<service_manager::Connector> GetServiceConnector() override;
 
   // Creates a new download item and call |callback|.
   void CreateNewDownloadItemToStart(
@@ -257,6 +258,7 @@
       download::DownloadItemImpl* download) override;
   bool IsOffTheRecord() const override;
   void ReportBytesWasted(download::DownloadItemImpl* download) override;
+  service_manager::Connector* GetServiceManagerConnector() override;
 
   // Drops a download before it is created.
   void DropDownload();
diff --git a/content/browser/download/url_downloader_factory.cc b/content/browser/download/url_downloader_factory.cc
index 9d2c165..387b79dea 100644
--- a/content/browser/download/url_downloader_factory.cc
+++ b/content/browser/download/url_downloader_factory.cc
@@ -9,6 +9,7 @@
 #include "content/browser/download/download_request_core.h"
 #include "content/browser/download/url_downloader.h"
 #include "net/url_request/url_request_context_getter.h"
+#include "services/service_manager/public/cpp/connector.h"
 
 namespace content {
 
@@ -24,6 +25,7 @@
         url_loader_factory_getter,
     const download::URLSecurityPolicy& url_security_policy,
     scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   std::unique_ptr<net::URLRequest> url_request =
       DownloadRequestCore::CreateRequestOnIOThread(
diff --git a/content/browser/download/url_downloader_factory.h b/content/browser/download/url_downloader_factory.h
index 23b287f..6c70cc8a 100644
--- a/content/browser/download/url_downloader_factory.h
+++ b/content/browser/download/url_downloader_factory.h
@@ -35,6 +35,7 @@
           shared_url_loader_factory,
       const download::URLSecurityPolicy& url_security_policy,
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) override;
 };
 
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 2f3f35ad..b8770db 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -1053,14 +1053,19 @@
   DCHECK(!loader_);
 
 #if defined(OS_ANDROID)
-  if (navigation_handle_proxy_) {
+  if (navigation_handle_proxy_)
     navigation_handle_proxy_->DidFinish();
-    navigation_handle_proxy_.reset();
-  }
 #endif
 
+  // The below order of resets is necessary to avoid accessing null pointers.
+  // See https://crbug.com/958396.
   navigation_handle_.reset();
 
+#if defined(OS_ANDROID)
+  if (navigation_handle_proxy_)
+    navigation_handle_proxy_.reset();
+#endif
+
   // Reset the previously selected RenderFrameHost. This is expected to be null
   // at the beginning of a new navigation. See https://crbug.com/936962.
   DCHECK(render_frame_host_);
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 9def072a..8796630b 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -918,8 +918,6 @@
 
   // Scheduler-relevant features this frame is using, for use in metrics.
   // See comments at |scheduler_tracked_features_|.
-  // NOTE: It now always returns 0 for subframes.
-  // TODO(altimin): Support subframes here as well.
   uint64_t scheduler_tracked_features() const {
     return scheduler_tracked_features_;
   }
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc
index 5a237935..e781dbb1 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.cc
+++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -33,7 +33,6 @@
 #include "content/public/common/use_zoom_for_dsf_policy.h"
 #include "gpu/ipc/common/gpu_messages.h"
 #include "skia/ext/platform_canvas.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/base/ui_base_switches_util.h"
 #include "ui/events/base_event_utils.h"
 #include "ui/gfx/geometry/dip_util.h"
@@ -359,14 +358,6 @@
 
 void RenderWidgetHostViewGuest::OnAttached() {
   RegisterFrameSinkId();
-#if defined(USE_AURA)
-  if (features::IsMultiProcessMash()) {
-    aura::Env::GetInstance()->ScheduleEmbed(
-        GetWindowTreeClientFromRenderer(),
-        base::BindOnce(&RenderWidgetHostViewGuest::OnGotEmbedToken,
-                       weak_ptr_factory_.GetWeakPtr()));
-  }
-#endif
   SendSurfaceInfoToEmbedder();
 }
 
@@ -804,16 +795,4 @@
   }
 }
 
-#if defined(USE_AURA)
-void RenderWidgetHostViewGuest::OnGotEmbedToken(
-    const base::UnguessableToken& token) {
-  if (!guest_)
-    return;
-
-  guest_->SendMessageToEmbedder(
-      std::make_unique<BrowserPluginMsg_SetMusEmbedToken>(
-          guest_->browser_plugin_instance_id(), token));
-}
-#endif
-
 }  // namespace content
diff --git a/content/browser/frame_host/render_widget_host_view_guest.h b/content/browser/frame_host/render_widget_host_view_guest.h
index e3e2f8c..3c568ad 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.h
+++ b/content/browser/frame_host/render_widget_host_view_guest.h
@@ -24,10 +24,6 @@
 #include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/native_widget_types.h"
 
-namespace base {
-class UnguessableToken;
-}
-
 namespace content {
 class BrowserPluginGuest;
 class RenderWidgetHost;
@@ -187,10 +183,6 @@
   void ProcessTouchpadZoomEventAckInRoot(const blink::WebGestureEvent& event,
                                          InputEventAckState ack_result);
 
-#if defined(USE_AURA)
-  void OnGotEmbedToken(const base::UnguessableToken& token);
-#endif
-
   // BrowserPluginGuest and RenderWidgetHostViewGuest's lifetimes are not tied
   // to one another, therefore we access |guest_| through WeakPtr.
   base::WeakPtr<BrowserPluginGuest> guest_;
diff --git a/content/browser/geolocation/geolocation_service_impl_unittest.cc b/content/browser/geolocation/geolocation_service_impl_unittest.cc
index f473c2b..d4ee6f50 100644
--- a/content/browser/geolocation/geolocation_service_impl_unittest.cc
+++ b/content/browser/geolocation/geolocation_service_impl_unittest.cc
@@ -32,11 +32,11 @@
 using blink::mojom::GeolocationService;
 using blink::mojom::GeolocationServicePtr;
 
-typedef base::Callback<void(PermissionStatus)> PermissionCallback;
-
 namespace content {
 namespace {
 
+using PermissionCallback = base::OnceCallback<void(PermissionStatus)>;
+
 double kMockLatitude = 1.0;
 double kMockLongitude = 10.0;
 GURL kMainUrl = GURL("https://www.google.com/maps");
@@ -52,24 +52,24 @@
                         RenderFrameHost* render_frame_host,
                         const GURL& requesting_origin,
                         bool user_gesture,
-                        const PermissionCallback& callback) override {
+                        PermissionCallback callback) override {
     EXPECT_EQ(permissions, PermissionType::GEOLOCATION);
     EXPECT_TRUE(user_gesture);
-    request_callback_.Run(callback);
+    request_callback_.Run(std::move(callback));
     return request_id_;
   }
 
   void SetRequestId(int request_id) { request_id_ = request_id; }
 
   void SetRequestCallback(
-      const base::Callback<void(const PermissionCallback&)>& request_callback) {
-    request_callback_ = request_callback;
+      base::RepeatingCallback<void(PermissionCallback)> request_callback) {
+    request_callback_ = std::move(request_callback);
   }
 
  private:
   int request_id_;
 
-  base::Callback<void(const PermissionCallback&)> request_callback_;
+  base::RepeatingCallback<void(PermissionCallback)> request_callback_;
 };
 
 class GeolocationServiceTest : public RenderViewHostImplTestHarness {
@@ -156,7 +156,7 @@
   CreateEmbeddedFrameAndGeolocationService(/*allow_via_feature_policy=*/false);
 
   permission_manager()->SetRequestCallback(
-      base::BindRepeating([](const PermissionCallback& callback) {
+      base::BindRepeating([](PermissionCallback callback) {
         ADD_FAILURE() << "Permissions checked unexpectedly.";
       }));
   GeolocationPtr geolocation;
@@ -180,8 +180,8 @@
   CreateEmbeddedFrameAndGeolocationService(/*allow_via_feature_policy=*/true);
 
   permission_manager()->SetRequestCallback(
-      base::BindRepeating([](const PermissionCallback& callback) {
-        callback.Run(PermissionStatus::GRANTED);
+      base::BindRepeating([](PermissionCallback callback) {
+        std::move(callback).Run(PermissionStatus::GRANTED);
       }));
   GeolocationPtr geolocation;
   service()->CreateGeolocation(
@@ -207,8 +207,8 @@
 TEST_F(GeolocationServiceTest, PermissionGrantedSync) {
   CreateEmbeddedFrameAndGeolocationService(/*allow_via_feature_policy=*/true);
   permission_manager()->SetRequestCallback(
-      base::BindRepeating([](const PermissionCallback& callback) {
-        callback.Run(PermissionStatus::GRANTED);
+      base::BindRepeating([](PermissionCallback callback) {
+        std::move(callback).Run(PermissionStatus::GRANTED);
       }));
   GeolocationPtr geolocation;
   service()->CreateGeolocation(
@@ -234,8 +234,8 @@
 TEST_F(GeolocationServiceTest, PermissionDeniedSync) {
   CreateEmbeddedFrameAndGeolocationService(/*allow_via_feature_policy=*/true);
   permission_manager()->SetRequestCallback(
-      base::BindRepeating([](const PermissionCallback& callback) {
-        callback.Run(PermissionStatus::DENIED);
+      base::BindRepeating([](PermissionCallback callback) {
+        std::move(callback).Run(PermissionStatus::DENIED);
       }));
   GeolocationPtr geolocation;
   service()->CreateGeolocation(
@@ -257,13 +257,10 @@
   CreateEmbeddedFrameAndGeolocationService(/*allow_via_feature_policy=*/true);
   permission_manager()->SetRequestId(42);
   permission_manager()->SetRequestCallback(
-      base::BindRepeating([](const PermissionCallback& permission_callback) {
+      base::BindRepeating([](PermissionCallback permission_callback) {
         base::ThreadTaskRunnerHandle::Get()->PostTask(
-            FROM_HERE, base::BindOnce(
-                           [](const PermissionCallback& callback) {
-                             callback.Run(PermissionStatus::GRANTED);
-                           },
-                           permission_callback));
+            FROM_HERE, base::BindOnce(std::move(permission_callback),
+                                      PermissionStatus::GRANTED));
       }));
   GeolocationPtr geolocation;
   service()->CreateGeolocation(
@@ -290,13 +287,10 @@
   CreateEmbeddedFrameAndGeolocationService(/*allow_via_feature_policy=*/true);
   permission_manager()->SetRequestId(42);
   permission_manager()->SetRequestCallback(
-      base::BindRepeating([](const PermissionCallback& permission_callback) {
+      base::BindRepeating([](PermissionCallback permission_callback) {
         base::ThreadTaskRunnerHandle::Get()->PostTask(
-            FROM_HERE, base::BindOnce(
-                           [](const PermissionCallback& callback) {
-                             callback.Run(PermissionStatus::DENIED);
-                           },
-                           permission_callback));
+            FROM_HERE, base::BindOnce(std::move(permission_callback),
+                                      PermissionStatus::DENIED));
       }));
   GeolocationPtr geolocation;
   service()->CreateGeolocation(
diff --git a/content/browser/idle/idle_browsertest.cc b/content/browser/idle/idle_browsertest.cc
new file mode 100644
index 0000000..d4ede6c2
--- /dev/null
+++ b/content/browser/idle/idle_browsertest.cc
@@ -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.
+
+#include "content/browser/idle/idle_manager.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using ::testing::NiceMock;
+
+namespace content {
+
+namespace {
+
+class MockIdleTimeProvider : public IdleManager::IdleTimeProvider {
+ public:
+  MockIdleTimeProvider() = default;
+  ~MockIdleTimeProvider() override = default;
+
+  MOCK_METHOD1(CalculateIdleState, ui::IdleState(base::TimeDelta));
+  MOCK_METHOD0(CalculateIdleTime, base::TimeDelta());
+  MOCK_METHOD0(CheckIdleStateIsLocked, bool());
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockIdleTimeProvider);
+};
+
+class IdleTest : public ContentBrowserTest {
+ public:
+  IdleTest() = default;
+  ~IdleTest() override = default;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    ContentBrowserTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitchASCII("enable-blink-features", "IdleDetection");
+  }
+};
+
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(IdleTest, Start) {
+  NavigateToURL(shell(), GetTestUrl(nullptr, "simple_page.html"));
+
+  auto mock_time_provider = std::make_unique<NiceMock<MockIdleTimeProvider>>();
+  auto* rph = static_cast<RenderProcessHostImpl*>(
+      shell()->web_contents()->GetMainFrame()->GetProcess());
+  IdleManager* idle_mgr =
+      static_cast<StoragePartitionImpl*>(rph->GetStoragePartition())
+          ->GetIdleManager();
+
+  // Test that statuses are updated after idleDetector.start().
+  std::string script = R"(
+    (async () => {
+        let idleDetector = new IdleDetector({threshold: 60});
+        await idleDetector.start();
+        return new Promise(function(resolve) {
+          let states = [];
+          idleDetector.addEventListener('change', e => {
+            let {user, screen} = idleDetector.state;
+            states.push(`${user}-${screen}`)
+            if (states.length >= 3) {
+              let states_str = states.join(',');
+              resolve(states_str);
+            }
+          });
+        });
+    }) ();
+  )";
+
+  EXPECT_CALL(*mock_time_provider, CalculateIdleTime())
+      // Initial state of the system.
+      .WillOnce(testing::Return(base::TimeDelta::FromSeconds(0)))
+      // Simulates a user going idle.
+      .WillOnce(testing::Return(base::TimeDelta::FromSeconds(60)))
+      // Simulates a screen getting locked after the user goes idle.
+      .WillOnce(testing::Return(base::TimeDelta::FromSeconds(60)))
+      // Simulates a user going back to active.
+      .WillRepeatedly(testing::Return(base::TimeDelta::FromSeconds(0)));
+
+  EXPECT_CALL(*mock_time_provider, CheckIdleStateIsLocked())
+      // Initial state of the system.
+      .WillOnce(testing::Return(false))
+      // Simulates unlocked screen while user goes idle.
+      .WillOnce(testing::Return(false))
+      // Simulates a screen getting locked after the user goes idle.
+      .WillOnce(testing::Return(true))
+      // Simulates an unlocked screen as user goes back to active.
+      .WillRepeatedly(testing::Return(false));
+
+  idle_mgr->SetIdleTimeProviderForTest(std::move(mock_time_provider));
+
+  std::string result = EvalJs(shell(), script).ExtractString();
+  std::vector<std::string> states = base::SplitString(
+      result, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+  EXPECT_EQ("idle-unlocked", states.at(0));
+  EXPECT_EQ("idle-locked", states.at(1));
+  EXPECT_EQ("active-unlocked", states.at(2));
+}
+
+}  // namespace content
diff --git a/content/browser/portal/portal.cc b/content/browser/portal/portal.cc
index 6701bbd..49e52fc 100644
--- a/content/browser/portal/portal.cc
+++ b/content/browser/portal/portal.cc
@@ -218,7 +218,7 @@
 }
 
 void Portal::PostMessageToHost(
-    const std::string& message,
+    blink::TransferableMessage message,
     const base::Optional<url::Origin>& target_origin) {
   DCHECK(GetPortalContents());
   if (target_origin) {
@@ -226,7 +226,8 @@
       return;
   }
   client().ForwardMessageFromGuest(
-      message, GetPortalContents()->GetMainFrame()->GetLastCommittedOrigin(),
+      std::move(message),
+      GetPortalContents()->GetMainFrame()->GetLastCommittedOrigin(),
       target_origin);
 }
 
diff --git a/content/browser/portal/portal.h b/content/browser/portal/portal.h
index 45af59d..8deae04 100644
--- a/content/browser/portal/portal.h
+++ b/content/browser/portal/portal.h
@@ -69,7 +69,7 @@
 
   // blink::mojom::PortalHost implementation
   void PostMessageToHost(
-      const std::string& message,
+      blink::TransferableMessage message,
       const base::Optional<url::Origin>& target_origin) override;
 
   // WebContentsObserver overrides.
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index 297346e9..f7a36e7a 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -437,7 +437,8 @@
 
   auto transfer_resource = viz::TransferableResource::MakeGL(
       result->GetTextureResult()->mailbox, GL_LINEAR, GL_TEXTURE_2D,
-      result->GetTextureResult()->sync_token);
+      result->GetTextureResult()->sync_token, result->size(),
+      false /* is_overlay_candidate */);
   std::unique_ptr<viz::SingleReleaseCallback> release_callback =
       result->TakeTextureOwnership();
 
diff --git a/content/browser/renderer_host/render_widget_targeter.cc b/content/browser/renderer_host/render_widget_targeter.cc
index 0cc660c..2f540fb 100644
--- a/content/browser/renderer_host/render_widget_targeter.cc
+++ b/content/browser/renderer_host/render_widget_targeter.cc
@@ -61,7 +61,7 @@
         metric_name_(metric_name) {
     TRACE_EVENT_ASYNC_BEGIN0(
         kTracingCategory, metric_name_,
-        TRACE_ID_WITH_SCOPE(metric_name_, TRACE_ID_LOCAL(id_)));
+        TRACE_ID_WITH_SCOPE("UmaTracker", TRACE_ID_LOCAL(id_)));
   }
   ~TracingUmaTracker() = default;
   TracingUmaTracker(TracingUmaTracker&& tracker) = default;
@@ -74,7 +74,7 @@
   void Stop() {
     TRACE_EVENT_ASYNC_END0(
         kTracingCategory, metric_name_,
-        TRACE_ID_WITH_SCOPE(metric_name_, TRACE_ID_LOCAL(id_)));
+        TRACE_ID_WITH_SCOPE("UmaTracker", TRACE_ID_LOCAL(id_)));
   }
 
  private:
diff --git a/content/browser/startup_helper.cc b/content/browser/startup_helper.cc
index ed24eb1..0f3b07b 100644
--- a/content/browser/startup_helper.cc
+++ b/content/browser/startup_helper.cc
@@ -23,19 +23,19 @@
   // Mobile config, for iOS see ios/web/app/web_main_loop.cc.
   return std::make_unique<base::ThreadPool::InitParams>(
       base::ThreadGroupParams(
-          base::RecommendedMaxNumberOfThreadsInPool(4, 8, 0.2, 0),
+          base::RecommendedMaxNumberOfThreadsInThreadGroup(4, 8, 0.2, 0),
           base::TimeDelta::FromSeconds(30)),
       base::ThreadGroupParams(
-          base::RecommendedMaxNumberOfThreadsInPool(6, 8, 0.6, 0),
+          base::RecommendedMaxNumberOfThreadsInThreadGroup(6, 8, 0.6, 0),
           base::TimeDelta::FromSeconds(30)));
 #else
   // Desktop config.
   return std::make_unique<base::ThreadPool::InitParams>(
       base::ThreadGroupParams(
-          base::RecommendedMaxNumberOfThreadsInPool(6, 8, 0.2, 0),
+          base::RecommendedMaxNumberOfThreadsInThreadGroup(6, 8, 0.2, 0),
           base::TimeDelta::FromSeconds(30)),
       base::ThreadGroupParams(
-          base::RecommendedMaxNumberOfThreadsInPool(16, 32, 0.6, 0),
+          base::RecommendedMaxNumberOfThreadsInThreadGroup(16, 32, 0.6, 0),
           base::TimeDelta::FromSeconds(30))
 #if defined(OS_WIN)
           ,
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn
index 3713e1a..16e1d03 100644
--- a/content/child/BUILD.gn
+++ b/content/child/BUILD.gn
@@ -138,6 +138,9 @@
 
   if (is_android) {
     deps += [ "//third_party/android_sdk:cpu_features" ]
+    if (notouch_build) {
+      configs += [ ":notouch_config" ]
+    }
   }
 
   if (is_linux) {
@@ -170,6 +173,10 @@
   ]
 }
 
+config("notouch_config") {
+  defines = [ "ENABLE_TOUCHLESS_UASTYLE_THEME" ]
+}
+
 # See comment at the top of //content/BUILD.gn for how this works.
 group("for_content_tests") {
   visibility = [ "//content/test/*" ]
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 2b2882c..e65e362 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -446,6 +446,10 @@
     {"xhtmlmp.css", IDR_UASTYLE_XHTMLMP_CSS, ui::SCALE_FACTOR_NONE, true},
     {"viewportAndroid.css", IDR_UASTYLE_VIEWPORT_ANDROID_CSS,
      ui::SCALE_FACTOR_NONE, true},
+#if defined(ENABLE_TOUCHLESS_UASTYLE_THEME)
+    {"touchless.css", IDR_UASTYLE_THEME_TOUCHLESS_CSS, ui::SCALE_FACTOR_NONE,
+     true},
+#endif
     {"viewportTelevision.css", IDR_UASTYLE_VIEWPORT_TELEVISION_CSS,
      ui::SCALE_FACTOR_NONE, true},
     {"inspect_tool_common.css", IDR_INSPECT_TOOL_COMMON_CSS,
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 7f09599..a6d70e8 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -404,9 +404,6 @@
   if (base::FeatureList::IsEnabled(features::kFeaturePolicyForSandbox))
     WebRuntimeFeatures::EnableFeaturePolicyForSandbox(true);
 
-  if (base::FeatureList::IsEnabled(features::kPageLifecycle))
-    WebRuntimeFeatures::EnablePageLifecycle(true);
-
 #if defined(OS_ANDROID)
   if (base::android::BuildInfo::GetInstance()->sdk_int() >=
       base::android::SDK_VERSION_P) {
diff --git a/content/common/browser_plugin/browser_plugin_messages.h b/content/common/browser_plugin/browser_plugin_messages.h
index 896c8a7..d876a1d 100644
--- a/content/common/browser_plugin/browser_plugin_messages.h
+++ b/content/common/browser_plugin/browser_plugin_messages.h
@@ -217,13 +217,4 @@
                      int /* browser_plugin_instance_id */,
                      bool /* enable */)
 
-#if defined(USE_AURA)
-// Sets the token that is used to embed the guest. |embed_token| is a token
-// that was generated from the window server and is expected to be supplied to
-// EmbedUsingToken().
-IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetMusEmbedToken,
-                     int /* browser_plugin_instance_id */,
-                     base::UnguessableToken /* embed_token */)
-#endif
-
 #endif  // CONTENT_COMMON_BROWSER_PLUGIN_BROWSER_PLUGIN_MESSAGES_H_
diff --git a/content/public/browser/devtools_frontend_host.h b/content/public/browser/devtools_frontend_host.h
index 8eff978..824a1f4 100644
--- a/content/public/browser/devtools_frontend_host.h
+++ b/content/public/browser/devtools_frontend_host.h
@@ -23,7 +23,8 @@
 // Note: DevToolsFrontendHost is not supported on Android.
 class DevToolsFrontendHost {
  public:
-  using HandleMessageCallback = base::Callback<void(const std::string&)>;
+  using HandleMessageCallback =
+      base::RepeatingCallback<void(const std::string&)>;
 
   // Creates a new DevToolsFrontendHost for RenderFrameHost where DevTools
   // frontend is loaded.
diff --git a/content/public/browser/permission_controller_delegate.h b/content/public/browser/permission_controller_delegate.h
index 2ba6de9..269d5e7 100644
--- a/content/public/browser/permission_controller_delegate.h
+++ b/content/public/browser/permission_controller_delegate.h
@@ -31,7 +31,7 @@
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback) = 0;
+      base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) = 0;
 
   // Requests multiple permissions on behalf of a frame identified by
   // render_frame_host.
@@ -48,8 +48,8 @@
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<void(
-          const std::vector<blink::mojom::PermissionStatus>&)>& callback) = 0;
+      base::OnceCallback<void(
+          const std::vector<blink::mojom::PermissionStatus>&)> callback) = 0;
 
   // Returns the permission status of a given requesting_origin/embedding_origin
   // tuple. This is not taking a RenderFrameHost because the call might happen
@@ -84,7 +84,8 @@
       content::PermissionType permission,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback) = 0;
+      base::RepeatingCallback<void(blink::mojom::PermissionStatus)>
+          callback) = 0;
 
   // Unregisters from permission status change notifications.
   // The |subscription_id| must match the value returned by the
diff --git a/content/public/browser/push_messaging_service.cc b/content/public/browser/push_messaging_service.cc
index 2abf1a3d..f2853b28 100644
--- a/content/public/browser/push_messaging_service.cc
+++ b/content/public/browser/push_messaging_service.cc
@@ -36,10 +36,10 @@
       base::BindOnce(callback, result, success, not_found));
 }
 
-void CallClosureFromIO(const base::Closure& callback,
+void CallClosureFromIO(base::OnceClosure callback,
                        blink::ServiceWorkerStatusCode status) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, callback);
+  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(callback));
 }
 
 void GetUserDataOnIO(
@@ -56,12 +56,12 @@
 void ClearPushSubscriptionIdOnIO(
     scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
     int64_t service_worker_registration_id,
-    const base::Closure& callback) {
+    base::OnceClosure callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   service_worker_context->ClearRegistrationUserData(
       service_worker_registration_id, {kPushRegistrationIdServiceWorkerKey},
-      base::BindOnce(&CallClosureFromIO, callback));
+      base::BindOnce(&CallClosureFromIO, std::move(callback)));
 }
 
 void StorePushSubscriptionOnIOForTesting(
@@ -70,14 +70,14 @@
     const GURL& origin,
     const std::string& subscription_id,
     const std::string& sender_id,
-    const base::Closure& callback) {
+    base::OnceClosure callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   service_worker_context->StoreRegistrationUserData(
       service_worker_registration_id, origin,
       {{kPushRegistrationIdServiceWorkerKey, subscription_id},
        {kPushSenderIdServiceWorkerKey, sender_id}},
-      base::BindOnce(&CallClosureFromIO, callback));
+      base::BindOnce(&CallClosureFromIO, std::move(callback)));
 }
 
 scoped_refptr<ServiceWorkerContextWrapper> GetServiceWorkerContext(
@@ -109,13 +109,13 @@
     BrowserContext* browser_context,
     const GURL& origin,
     int64_t service_worker_registration_id,
-    const base::Closure& callback) {
+    base::OnceClosure callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::PostTaskWithTraits(
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&ClearPushSubscriptionIdOnIO,
                      GetServiceWorkerContext(browser_context, origin),
-                     service_worker_registration_id, callback));
+                     service_worker_registration_id, std::move(callback)));
 }
 
 // static
diff --git a/content/public/browser/push_messaging_service.h b/content/public/browser/push_messaging_service.h
index 682a856..6f2375df 100644
--- a/content/public/browser/push_messaging_service.h
+++ b/content/public/browser/push_messaging_service.h
@@ -35,12 +35,12 @@
 class CONTENT_EXPORT PushMessagingService {
  public:
   using RegisterCallback =
-      base::Callback<void(const std::string& registration_id,
-                          const std::vector<uint8_t>& p256dh,
-                          const std::vector<uint8_t>& auth,
-                          mojom::PushRegistrationStatus status)>;
+      base::OnceCallback<void(const std::string& registration_id,
+                              const std::vector<uint8_t>& p256dh,
+                              const std::vector<uint8_t>& auth,
+                              mojom::PushRegistrationStatus status)>;
   using UnregisterCallback =
-      base::Callback<void(mojom::PushUnregistrationStatus)>;
+      base::OnceCallback<void(mojom::PushUnregistrationStatus)>;
   using SubscriptionInfoCallback =
       base::Callback<void(bool is_valid,
                           const std::vector<uint8_t>& p256dh,
@@ -67,7 +67,7 @@
                                      int render_frame_id,
                                      const PushSubscriptionOptions& options,
                                      bool user_gesture,
-                                     const RegisterCallback& callback) = 0;
+                                     RegisterCallback callback) = 0;
 
   // Subscribe the given |options.sender_info| with the push messaging service.
   // The frame is not known so if permission was not previously granted by the
@@ -77,7 +77,7 @@
   virtual void SubscribeFromWorker(const GURL& requesting_origin,
                                    int64_t service_worker_registration_id,
                                    const PushSubscriptionOptions& options,
-                                   const RegisterCallback& callback) = 0;
+                                   RegisterCallback callback) = 0;
 
   // Retrieves the subscription associated with |origin| and
   // |service_worker_registration_id|, validates that the provided
@@ -99,7 +99,7 @@
                            const GURL& requesting_origin,
                            int64_t service_worker_registration_id,
                            const std::string& sender_id,
-                           const UnregisterCallback& callback) = 0;
+                           UnregisterCallback callback) = 0;
 
   // Returns whether subscriptions that do not mandate user visible UI upon
   // receiving a push message are supported. Influences permission request and
@@ -127,7 +127,7 @@
   static void ClearPushSubscriptionId(BrowserContext* browser_context,
                                       const GURL& origin,
                                       int64_t service_worker_registration_id,
-                                      const base::Closure& callback);
+                                      base::OnceClosure callback);
 
   // Stores a push subscription in the service worker for the given |origin|.
   // Must only be used by tests.
diff --git a/content/public/browser/renderer_preferences_util.cc b/content/public/browser/renderer_preferences_util.cc
index b7de4425..fee03cb 100644
--- a/content/public/browser/renderer_preferences_util.cc
+++ b/content/public/browser/renderer_preferences_util.cc
@@ -12,10 +12,6 @@
 #include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
 #include "ui/gfx/font_render_params.h"
 
-#if defined(OS_ANDROID)
-#include "content/browser/android/android_ui_constants.h"
-#endif
-
 namespace content {
 
 void UpdateFontRendererPreferencesFromSystemSettings(
@@ -30,22 +26,4 @@
   prefs->subpixel_rendering = params->subpixel_rendering;
 }
 
-void UpdateFocusRingPreferencesFromSystemSettings(
-    blink::mojom::RendererPreferences* prefs) {
-#if defined(OS_ANDROID)
-  prefs->is_focus_ring_outset = AndroidUiConstants::IsFocusRingOutset();
-
-  base::Optional<float> stroke_width =
-      AndroidUiConstants::GetMinimumStrokeWidthForFocusRing();
-  if (stroke_width)
-    prefs->minimum_stroke_width_for_focus_ring = *stroke_width;
-
-  base::Optional<SkColor> color = AndroidUiConstants::GetFocusRingColor();
-  if (color) {
-    prefs->use_custom_colors = true;
-    prefs->focus_ring_color = *color;
-  }
-#endif
-}
-
 }  // namespace content
diff --git a/content/public/browser/renderer_preferences_util.h b/content/public/browser/renderer_preferences_util.h
index bfd5be8..eb81d84 100644
--- a/content/public/browser/renderer_preferences_util.h
+++ b/content/public/browser/renderer_preferences_util.h
@@ -19,9 +19,6 @@
 CONTENT_EXPORT void UpdateFontRendererPreferencesFromSystemSettings(
     blink::mojom::RendererPreferences* prefs);
 
-CONTENT_EXPORT void UpdateFocusRingPreferencesFromSystemSettings(
-    blink::mojom::RendererPreferences* prefs);
-
 }  // namespace content
 
 #endif  // CONTENT_PUBLIC_BROWSER_RENDERER_PREFERENCES_UTIL_H_
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h
index 94113ae5..1d32d72 100644
--- a/content/public/common/common_param_traits_macros.h
+++ b/content/public/common/common_param_traits_macros.h
@@ -312,10 +312,6 @@
   IPC_STRUCT_TRAITS_MEMBER(subpixel_rendering)
   IPC_STRUCT_TRAITS_MEMBER(use_subpixel_positioning)
   IPC_STRUCT_TRAITS_MEMBER(focus_ring_color)
-#if defined(OS_ANDROID)
-  IPC_STRUCT_TRAITS_MEMBER(minimum_stroke_width_for_focus_ring)
-  IPC_STRUCT_TRAITS_MEMBER(is_focus_ring_outset)
-#endif
   IPC_STRUCT_TRAITS_MEMBER(active_selection_bg_color)
   IPC_STRUCT_TRAITS_MEMBER(active_selection_fg_color)
   IPC_STRUCT_TRAITS_MEMBER(inactive_selection_bg_color)
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index be0e385..927a37e 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -304,10 +304,6 @@
 #endif
 };
 
-// Blink PageLifecycle feature. See https://crbug.com/775194
-const base::Feature kPageLifecycle{"PageLifecycle",
-                                   base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Whether document level event listeners should default 'passive' to true.
 const base::Feature kPassiveDocumentEventListeners{
     "PassiveDocumentEventListeners", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -539,6 +535,11 @@
 const base::Feature kWebAssemblyCodeGC{"WebAssemblyCodeGC",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enable WebAssembly SIMD
+// https://github.com/WebAssembly/Simd
+const base::Feature kWebAssemblySimd{"WebAssemblySimd",
+                                     base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enable WebAssembly threads.
 // https://github.com/WebAssembly/threads
 const base::Feature kWebAssemblyThreads {
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index bce6055..174eed4 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -75,7 +75,6 @@
 CONTENT_EXPORT extern const base::Feature kOriginPolicy;
 CONTENT_EXPORT extern const base::Feature kOriginTrials;
 CONTENT_EXPORT extern const base::Feature kOverscrollHistoryNavigation;
-CONTENT_EXPORT extern const base::Feature kPageLifecycle;
 CONTENT_EXPORT extern const base::Feature kPassiveDocumentEventListeners;
 CONTENT_EXPORT extern const base::Feature kPassiveDocumentWheelEventListeners;
 CONTENT_EXPORT extern const base::Feature kPassiveEventListenersDueToFling;
@@ -124,6 +123,7 @@
 CONTENT_EXPORT extern const base::Feature kWebAssembly;
 CONTENT_EXPORT extern const base::Feature kWebAssemblyBaseline;
 CONTENT_EXPORT extern const base::Feature kWebAssemblyCodeGC;
+CONTENT_EXPORT extern const base::Feature kWebAssemblySimd;
 CONTENT_EXPORT extern const base::Feature kWebAssemblyThreads;
 CONTENT_EXPORT extern const base::Feature kWebAssemblyTrapHandler;
 CONTENT_EXPORT extern const base::Feature kWebAuth;
diff --git a/content/public/test/mock_permission_manager.cc b/content/public/test/mock_permission_manager.cc
index caf02a50..83ba750 100644
--- a/content/public/test/mock_permission_manager.cc
+++ b/content/public/test/mock_permission_manager.cc
@@ -18,7 +18,7 @@
     RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) {
   return PermissionController::kNoPendingOperation;
 }
 
@@ -27,8 +27,8 @@
     RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<
-        void(const std::vector<blink::mojom::PermissionStatus>&)>& callback) {
+    base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)>
+        callback) {
   return PermissionController::kNoPendingOperation;
 }
 
@@ -36,7 +36,7 @@
     PermissionType permission,
     RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
   // Return a fake subscription_id.
   return 0;
 }
diff --git a/content/public/test/mock_permission_manager.h b/content/public/test/mock_permission_manager.h
index d7da1d8..a193bd00 100644
--- a/content/public/test/mock_permission_manager.h
+++ b/content/public/test/mock_permission_manager.h
@@ -32,20 +32,19 @@
                    PermissionType permission,
                    content::RenderFrameHost* render_frame_host,
                    const GURL& requesting_origin));
-  int RequestPermission(
-      PermissionType permission,
-      RenderFrameHost* render_frame_host,
-      const GURL& requesting_origin,
-      bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
-      override;
+  int RequestPermission(PermissionType permission,
+                        RenderFrameHost* render_frame_host,
+                        const GURL& requesting_origin,
+                        bool user_gesture,
+                        base::OnceCallback<void(blink::mojom::PermissionStatus)>
+                            callback) override;
   int RequestPermissions(
       const std::vector<PermissionType>& permission,
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<
-          void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
+      base::OnceCallback<
+          void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
       override;
   void ResetPermission(PermissionType permission,
                        const GURL& requesting_origin,
@@ -54,7 +53,7 @@
       PermissionType permission,
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
+      base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
       override;
   void UnsubscribePermissionStatusChange(int subscription_id) override {}
 
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 9fb4d72ca..dea96bf 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -722,12 +722,6 @@
   ]
   allow_circular_includes_from = []
 
-  if (use_aura) {
-    public_deps += [ "//content/renderer/mus" ]
-    allow_circular_includes_from += [ "//content/renderer/mus" ]
-    deps += [ "//services/ws/public/cpp" ]
-  }
-
   if (use_external_popup_menu) {
     sources += [
       "external_popup_menu.cc",
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
index 5e38e8c..5bbfd2f 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -47,14 +47,8 @@
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/public/web/web_plugin_container.h"
 #include "third_party/blink/public/web/web_view.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
-#if defined(USE_AURA)
-#include "content/renderer/mus/mus_embedded_frame.h"
-#include "content/renderer/mus/renderer_window_tree_client.h"
-#endif
-
 using blink::WebPluginContainer;
 using blink::WebPoint;
 using blink::WebRect;
@@ -136,9 +130,6 @@
                         OnDidUpdateVisualProperties)
     IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor)
     IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetMouseLock, OnSetMouseLock)
-#if defined(USE_AURA)
-    IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetMusEmbedToken, OnSetMusEmbedToken)
-#endif
     IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
                         OnShouldAcceptTouchEvents)
   IPC_END_MESSAGE_MAP()
@@ -173,14 +164,6 @@
             ->GetDocument()
             .IsPluginDocument();
   }
-#if defined(USE_AURA)
-  if (pending_embed_token_) {
-    base::Optional<base::UnguessableToken> embed_token =
-        std::move(pending_embed_token_);
-    CreateMusWindowAndEmbed(*embed_token);
-  }
-#endif
-
   BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_Attach(
       render_frame_routing_id_,
       browser_plugin_instance_id_,
@@ -219,28 +202,6 @@
       .GetCurrentLocalSurfaceIdAllocation();
 }
 
-#if defined(USE_AURA)
-void BrowserPlugin::CreateMusWindowAndEmbed(
-    const base::UnguessableToken& embed_token) {
-  RenderFrameImpl* render_frame =
-      RenderFrameImpl::FromRoutingID(render_frame_routing_id_);
-  if (!render_frame) {
-    pending_embed_token_ = embed_token;
-    return;
-  }
-  RendererWindowTreeClient* renderer_window_tree_client =
-      RendererWindowTreeClient::Get(
-          render_frame->GetLocalRootRenderWidget()->routing_id());
-  DCHECK(renderer_window_tree_client);
-  mus_embedded_frame_ =
-      renderer_window_tree_client->CreateMusEmbeddedFrame(this, embed_token);
-  if (attached() && GetLocalSurfaceIdAllocation().IsValid()) {
-    mus_embedded_frame_->SetWindowBounds(GetLocalSurfaceIdAllocation(),
-                                         FrameRectInPixels());
-  }
-}
-#endif
-
 void BrowserPlugin::SynchronizeVisualProperties() {
   bool size_changed = !sent_visual_properties_ ||
                       sent_visual_properties_->auto_resize_enabled !=
@@ -311,13 +272,6 @@
 
   if (visual_properties_changed && attached())
     sent_visual_properties_ = pending_visual_properties_;
-
-#if defined(USE_AURA)
-  if (features::IsMultiProcessMash() && mus_embedded_frame_) {
-    mus_embedded_frame_->SetWindowBounds(GetLocalSurfaceIdAllocation(),
-                                         FrameRectInPixels());
-  }
-#endif
 }
 
 void BrowserPlugin::OnAdvanceFocus(int browser_plugin_instance_id,
@@ -400,20 +354,6 @@
   }
 }
 
-#if defined(USE_AURA)
-void BrowserPlugin::OnSetMusEmbedToken(
-    int instance_id,
-    const base::UnguessableToken& embed_token) {
-  DCHECK(features::IsMultiProcessMash());
-  if (!attached_) {
-    pending_embed_token_ = embed_token;
-  } else {
-    pending_embed_token_.reset();
-    CreateMusWindowAndEmbed(embed_token);
-  }
-}
-#endif
-
 void BrowserPlugin::OnShouldAcceptTouchEvents(int browser_plugin_instance_id,
                                               bool accept) {
   if (Container()) {
@@ -423,18 +363,6 @@
   }
 }
 
-gfx::Rect BrowserPlugin::FrameRectInPixels() const {
-  const float device_scale_factor = GetDeviceScaleFactor();
-  return gfx::Rect(
-      gfx::ScaleToFlooredPoint(screen_space_rect().origin(),
-                               device_scale_factor),
-      gfx::ScaleToCeiledSize(screen_space_rect().size(), device_scale_factor));
-}
-
-float BrowserPlugin::GetDeviceScaleFactor() const {
-  return pending_visual_properties_.screen_info.device_scale_factor;
-}
-
 RenderWidget* BrowserPlugin::GetMainWidget() const {
   RenderFrameImpl* frame =
       RenderFrameImpl::FromRoutingID(render_frame_routing_id());
@@ -838,15 +766,6 @@
   return true;
 }
 
-#if defined(USE_AURA)
-void BrowserPlugin::OnMusEmbeddedFrameSinkIdAllocated(
-    const viz::FrameSinkId& frame_sink_id) {
-  // RendererWindowTreeClient should only call this when mus is hosting viz.
-  DCHECK(features::IsMultiProcessMash());
-  OnGuestReady(browser_plugin_instance_id_, frame_sink_id);
-}
-#endif
-
 cc::Layer* BrowserPlugin::GetLayer() {
   return embedded_layer_.get();
 }
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h
index 89c2b67d..a81d50fb 100644
--- a/content/renderer/browser_plugin/browser_plugin.h
+++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -26,14 +26,6 @@
 #include "third_party/blink/public/web/web_input_method_controller.h"
 #include "third_party/blink/public/web/web_node.h"
 
-#if defined(USE_AURA)
-#include "content/renderer/mus/mus_embedded_frame_delegate.h"
-#endif
-
-namespace base {
-class UnguessableToken;
-}
-
 namespace cc {
 class Layer;
 class RenderFrameMetadata;
@@ -45,14 +37,7 @@
 class BrowserPluginManager;
 class ChildFrameCompositingHelper;
 
-#if defined(USE_AURA)
-class MusEmbeddedFrame;
-#endif
-
 class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
-#if defined(USE_AURA)
-                                     public MusEmbeddedFrameDelegate,
-#endif
                                      public ChildFrameCompositor,
                                      public MouseLockDispatcher::LockTarget {
  public:
@@ -175,8 +160,6 @@
   const gfx::Rect& screen_space_rect() const {
     return pending_visual_properties_.screen_space_rect;
   }
-  gfx::Rect FrameRectInPixels() const;
-  float GetDeviceScaleFactor() const;
   RenderWidget* GetMainWidget() const;
 
   const ScreenInfo& screen_info() const {
@@ -185,10 +168,6 @@
 
   void UpdateInternalInstanceId();
 
-#if defined(USE_AURA)
-  void CreateMusWindowAndEmbed(const base::UnguessableToken& embed_token);
-#endif
-
   // IPC message handlers.
   // Please keep in alphabetical order.
   void OnAdvanceFocus(int instance_id, bool reverse);
@@ -204,18 +183,8 @@
   void OnSetContentsOpaque(int instance_id, bool opaque);
   void OnSetCursor(int instance_id, const WebCursor& cursor);
   void OnSetMouseLock(int instance_id, bool enable);
-#if defined(USE_AURA)
-  void OnSetMusEmbedToken(int instance_id,
-                          const base::UnguessableToken& embed_token);
-#endif
   void OnShouldAcceptTouchEvents(int instance_id, bool accept);
 
-#if defined(USE_AURA)
-  // MusEmbeddedFrameDelegate
-  void OnMusEmbeddedFrameSinkIdAllocated(
-      const viz::FrameSinkId& frame_sink_id) override;
-#endif
-
   // ChildFrameCompositor:
   cc::Layer* GetLayer() override;
   void SetLayer(scoped_refptr<cc::Layer> layer,
@@ -267,13 +236,6 @@
   // own this. The delegate destroys itself.
   base::WeakPtr<BrowserPluginDelegate> delegate_;
 
-#if defined(USE_AURA)
-  // Set if OnSetMusEmbedToken() is called before attached.
-  base::Optional<base::UnguessableToken> pending_embed_token_;
-
-  std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame_;
-#endif
-
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
   // Pointer to the RenderWidget that embeds this plugin.
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc
index 5871ce9..d34a5e5 100644
--- a/content/renderer/media/media_factory.cc
+++ b/content/renderer/media/media_factory.cc
@@ -49,7 +49,6 @@
 #include "third_party/blink/public/platform/web_video_frame_submitter.h"
 #include "third_party/blink/public/web/blink.h"
 #include "third_party/blink/public/web/web_local_frame.h"
-#include "ui/base/ui_base_features.h"
 #include "url/origin.h"
 
 #if defined(OS_ANDROID)
@@ -141,9 +140,6 @@
 // static
 blink::WebMediaPlayer::SurfaceLayerMode
 MediaFactory::GetVideoSurfaceLayerMode() {
-  if (features::IsMultiProcessMash())
-    return blink::WebMediaPlayer::SurfaceLayerMode::kNever;
-
 #if defined(OS_ANDROID)
   if (base::FeatureList::IsEnabled(media::kDisableSurfaceLayerForVideo))
     return blink::WebMediaPlayer::SurfaceLayerMode::kNever;
diff --git a/content/renderer/media/webrtc/mock_peer_connection_impl.h b/content/renderer/media/webrtc/mock_peer_connection_impl.h
index 4874874d..a5156d8 100644
--- a/content/renderer/media/webrtc/mock_peer_connection_impl.h
+++ b/content/renderer/media/webrtc/mock_peer_connection_impl.h
@@ -207,8 +207,8 @@
     return PeerConnectionInterface::kIceGatheringNew;
   }
 
-  bool StartRtcEventLog(rtc::PlatformFile file,
-                        int64_t max_size_bytes) override {
+  bool StartRtcEventLog(std::unique_ptr<webrtc::RtcEventLogOutput> output,
+                        int64_t output_period_ms) override {
     NOTIMPLEMENTED();
     return false;
   }
diff --git a/content/renderer/mus/BUILD.gn b/content/renderer/mus/BUILD.gn
deleted file mode 100644
index 391e93c5..0000000
--- a/content/renderer/mus/BUILD.gn
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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.
-
-static_library("mus") {
-  # Depend on this only via //content/renderer.
-  visibility = [ "//content/renderer/*" ]
-
-  sources = [
-    "mus_embedded_frame.cc",
-    "mus_embedded_frame.h",
-    "mus_embedded_frame_delegate.h",
-    "render_widget_window_tree_client_factory.cc",
-    "render_widget_window_tree_client_factory.h",
-    "renderer_window_tree_client.cc",
-    "renderer_window_tree_client.h",
-  ]
-
-  configs += [ "//content:content_implementation" ]
-
-  public_deps = [
-    "//content/public/common:common_sources",
-  ]
-
-  deps = [
-    "//base",
-    "//cc",
-    "//cc/mojo_embedder",
-    "//components/viz/client",
-    "//content/common",
-    "//content/public/child:child_sources",
-    "//media/mojo/interfaces:remoting",
-    "//services/service_manager/public/cpp",
-    "//services/ws/public/cpp",
-    "//services/ws/public/mojom",
-    "//third_party/blink/public:blink",
-    "//ui/events:events",
-    "//ui/events:events_base",
-    "//ui/events/blink",
-    "//ui/gfx/geometry/mojo",
-  ]
-}
diff --git a/content/renderer/mus/OWNERS b/content/renderer/mus/OWNERS
deleted file mode 100644
index fa103a4a..0000000
--- a/content/renderer/mus/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-ben@chromium.org
-sadrul@chromium.org
-fsamuel@chromium.org
-rjkroege@chromium.org
-
-# COMPONENT: Internals>Services>WindowService
diff --git a/content/renderer/mus/mus_embedded_frame.cc b/content/renderer/mus/mus_embedded_frame.cc
deleted file mode 100644
index cebc33c..0000000
--- a/content/renderer/mus/mus_embedded_frame.cc
+++ /dev/null
@@ -1,123 +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 "content/renderer/mus/mus_embedded_frame.h"
-
-#include <map>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/lazy_instance.h"
-#include "cc/base/switches.h"
-#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
-#include "components/viz/client/hit_test_data_provider.h"
-#include "components/viz/client/local_surface_id_provider.h"
-#include "content/renderer/mus/renderer_window_tree_client.h"
-#include "services/ws/public/cpp/property_type_converters.h"
-#include "services/ws/public/mojom/window_manager.mojom.h"
-
-namespace content {
-namespace {
-
-// Callback from embedding a child frame.
-void OnEmbedAck(bool success) {
-  DCHECK(success);
-}
-
-}  // namespace
-
-MusEmbeddedFrame::~MusEmbeddedFrame() {
-  renderer_window_tree_client_->OnEmbeddedFrameDestroyed(this);
-
-  // If the tree changed the old tree the window was created in was dropped and
-  // the server implictly cleaned up. As such, no need to do cleanup here (and
-  // we don't have a handle to the right WindowTree at this point).
-  if (tree_changed_)
-    return;
-
-  // If there is |pending_state_| it means we didn't actually create the window
-  // yet and there is nothing to do.
-  if (pending_state_)
-    return;
-
-  window_tree()->DeleteWindow(GetAndAdvanceNextChangeId(), window_id_);
-}
-
-void MusEmbeddedFrame::SetWindowBounds(
-    const viz::LocalSurfaceIdAllocation& local_surface_id_allocation,
-    const gfx::Rect& bounds) {
-  if (tree_changed_)
-    return;
-
-  if (!window_tree()) {
-    DCHECK(pending_state_);
-    pending_state_->bounds = bounds;
-    pending_state_->local_surface_id_allocation = local_surface_id_allocation;
-    pending_state_->was_set_window_bounds_called = true;
-    return;
-  }
-
-  window_tree()->SetWindowBounds(GetAndAdvanceNextChangeId(), window_id_,
-                                 bounds, local_surface_id_allocation);
-}
-
-MusEmbeddedFrame::MusEmbeddedFrame(
-    RendererWindowTreeClient* renderer_window_tree_client,
-    MusEmbeddedFrameDelegate* delegate,
-    ws::ClientSpecificId window_id,
-    const base::UnguessableToken& token)
-    : renderer_window_tree_client_(renderer_window_tree_client),
-      delegate_(delegate),
-      window_id_(window_id) {
-  if (!window_tree()) {
-    pending_state_ = std::make_unique<PendingState>();
-    pending_state_->token = token;
-    return;
-  }
-  CreateChildWindowAndEmbed(token);
-}
-
-void MusEmbeddedFrame::CreateChildWindowAndEmbed(
-    const base::UnguessableToken& token) {
-  // Set a name for debugging.
-  base::flat_map<std::string, std::vector<uint8_t>> properties;
-  properties[ws::mojom::WindowManager::kName_Property] =
-      mojo::ConvertTo<std::vector<uint8_t>>(std::string("RendererFrame"));
-  window_tree()->NewWindow(GetAndAdvanceNextChangeId(), window_id_, properties);
-  window_tree()->AddWindow(GetAndAdvanceNextChangeId(),
-                           renderer_window_tree_client_->root_window_id_,
-                           window_id_);
-  window_tree()->EmbedUsingToken(window_id_, token, 0,
-                                 base::BindOnce(&OnEmbedAck));
-}
-
-void MusEmbeddedFrame::OnTreeAvailable() {
-  // See header for description, always called before OnTreeWillChange().
-  DCHECK(!tree_changed_);
-  std::unique_ptr<PendingState> pending_state = std::move(pending_state_);
-  CreateChildWindowAndEmbed(pending_state->token);
-  if (pending_state->was_set_window_bounds_called)
-    SetWindowBounds(pending_state->local_surface_id_allocation,
-                    pending_state->bounds);
-}
-
-void MusEmbeddedFrame::OnTreeWillChange() {
-  tree_changed_ = true;
-}
-
-uint32_t MusEmbeddedFrame::GetAndAdvanceNextChangeId() {
-  return renderer_window_tree_client_->GetAndAdvanceNextChangeId();
-}
-
-ws::mojom::WindowTree* MusEmbeddedFrame::window_tree() {
-  // Once |tree_changed_| is true the WindowTree this instance used has changed
-  // and it no longer makes sense to use it (the original window was deleted).
-  return tree_changed_ ? nullptr : renderer_window_tree_client_->tree_.get();
-}
-
-MusEmbeddedFrame::PendingState::PendingState() = default;
-
-MusEmbeddedFrame::PendingState::~PendingState() = default;
-
-}  // namespace content
diff --git a/content/renderer/mus/mus_embedded_frame.h b/content/renderer/mus/mus_embedded_frame.h
deleted file mode 100644
index 83634709..0000000
--- a/content/renderer/mus/mus_embedded_frame.h
+++ /dev/null
@@ -1,88 +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 CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_H_
-#define CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/unguessable_token.h"
-#include "components/viz/common/surfaces/local_surface_id_allocation.h"
-#include "services/ws/common/types.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace ws {
-namespace mojom {
-class WindowTree;
-}
-}  // namespace ui
-
-namespace content {
-
-class MusEmbeddedFrameDelegate;
-class RendererWindowTreeClient;
-
-// MusEmbeddedFrame represents an embedding of an OOPIF frame. Internally this
-// creates a window in the window server and calls Embed().
-class MusEmbeddedFrame {
- public:
-  ~MusEmbeddedFrame();
-
-  // Sets the bounds (in pixels) of the embedded frame.
-  void SetWindowBounds(
-      const viz::LocalSurfaceIdAllocation& local_surface_id_allocation,
-      const gfx::Rect& bounds);
-
- private:
-  friend class RendererWindowTreeClient;
-
-  // Stores state that needs to pushed to the server once the connection has
-  // been established (OnEmbed() is called).
-  struct PendingState {
-    PendingState();
-    ~PendingState();
-
-    base::UnguessableToken token;
-    viz::LocalSurfaceIdAllocation local_surface_id_allocation;
-    gfx::Rect bounds;
-    // True if SetWindowBounds() was called.
-    bool was_set_window_bounds_called = false;
-  };
-
-  MusEmbeddedFrame(RendererWindowTreeClient* renderer_window_tree_client,
-                   MusEmbeddedFrameDelegate* delegate,
-                   ws::ClientSpecificId window_id,
-                   const base::UnguessableToken& token);
-
-  // Called once the WindowTree has been obtained. This is only called if
-  // the MusEmbeddedFrame is created before the WindowTree has been obtained.
-  void OnTreeAvailable();
-
-  // Called when the WindowTree held by |renderer_window_tree_client_| is about
-  // to change. This means the renderer was reembeded.
-  void OnTreeWillChange();
-
-  // Does the actual embedding.
-  void CreateChildWindowAndEmbed(const base::UnguessableToken& token);
-
-  uint32_t GetAndAdvanceNextChangeId();
-
-  ws::mojom::WindowTree* window_tree();
-
-  RendererWindowTreeClient* renderer_window_tree_client_;
-  MusEmbeddedFrameDelegate* delegate_;
-  const ws::ClientSpecificId window_id_;
-
-  std::unique_ptr<PendingState> pending_state_;
-
-  // If set, the WindowTree that state was created on has changed.
-  bool tree_changed_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(MusEmbeddedFrame);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_H_
diff --git a/content/renderer/mus/mus_embedded_frame_delegate.h b/content/renderer/mus/mus_embedded_frame_delegate.h
deleted file mode 100644
index cd61b38..0000000
--- a/content/renderer/mus/mus_embedded_frame_delegate.h
+++ /dev/null
@@ -1,26 +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 CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_DELEGATE_H_
-#define CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_DELEGATE_H_
-
-namespace viz {
-class FrameSinkId;
-}  // namespace viz
-
-namespace content {
-
-class MusEmbeddedFrameDelegate {
- public:
-  // Called when mus determines the FrameSinkId.
-  virtual void OnMusEmbeddedFrameSinkIdAllocated(
-      const viz::FrameSinkId& frame_sink_id) = 0;
-
- protected:
-  virtual ~MusEmbeddedFrameDelegate() {}
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_DELEGATE_H_
diff --git a/content/renderer/mus/render_widget_window_tree_client_factory.cc b/content/renderer/mus/render_widget_window_tree_client_factory.cc
deleted file mode 100644
index e06cadb..0000000
--- a/content/renderer/mus/render_widget_window_tree_client_factory.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// 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.
-
-#include "content/renderer/mus/render_widget_window_tree_client_factory.h"
-
-#include <stdint.h>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/common/render_widget_window_tree_client_factory.mojom.h"
-#include "content/public/common/connection_filter.h"
-#include "content/public/common/service_manager_connection.h"
-#include "content/renderer/mus/renderer_window_tree_client.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "services/service_manager/public/cpp/service.h"
-#include "services/ws/public/mojom/window_tree.mojom.h"
-#include "url/gurl.h"
-
-namespace content {
-
-namespace {
-
-void BindMusConnectionOnMainThread(
-    uint32_t routing_id,
-    ws::mojom::WindowTreeClientRequest request,
-    mojom::RenderWidgetWindowTreeClientRequest
-        render_widget_window_tree_client_request) {
-  RendererWindowTreeClient::CreateIfNecessary(routing_id);
-  RendererWindowTreeClient::Get(routing_id)
-      ->Bind(std::move(request),
-             std::move(render_widget_window_tree_client_request));
-}
-
-// This object's lifetime is managed by ServiceManagerConnection because it's a
-// registered with it.
-class RenderWidgetWindowTreeClientFactoryImpl
-    : public ConnectionFilter,
-      public mojom::RenderWidgetWindowTreeClientFactory {
- public:
-  RenderWidgetWindowTreeClientFactoryImpl() {
-    main_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get();
-  }
-
-  ~RenderWidgetWindowTreeClientFactoryImpl() override {}
-
- private:
-  // ConnectionFilter implementation:
-  void OnBindInterface(const service_manager::BindSourceInfo& source_info,
-                       const std::string& interface_name,
-                       mojo::ScopedMessagePipeHandle* interface_pipe,
-                       service_manager::Connector* connector) override {
-    if (interface_name == mojom::RenderWidgetWindowTreeClientFactory::Name_) {
-      bindings_.AddBinding(this,
-                           mojom::RenderWidgetWindowTreeClientFactoryRequest(
-                               std::move(*interface_pipe)));
-    }
-  }
-
-  // mojom::RenderWidgetWindowTreeClientFactory implementation.
-  void CreateWindowTreeClientForRenderWidget(
-      uint32_t routing_id,
-      ws::mojom::WindowTreeClientRequest request,
-      mojom::RenderWidgetWindowTreeClientRequest
-          render_widget_window_tree_client_request) override {
-    main_thread_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&BindMusConnectionOnMainThread, routing_id,
-                       std::move(request),
-                       std::move(render_widget_window_tree_client_request)));
-  }
-
-  scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner_;
-  mojo::BindingSet<mojom::RenderWidgetWindowTreeClientFactory> bindings_;
-
-  DISALLOW_COPY_AND_ASSIGN(RenderWidgetWindowTreeClientFactoryImpl);
-};
-
-}  // namespace
-
-void CreateRenderWidgetWindowTreeClientFactory(
-    ServiceManagerConnection* connection) {
-  connection->AddConnectionFilter(
-      std::make_unique<RenderWidgetWindowTreeClientFactoryImpl>());
-}
-
-}  // namespace content
diff --git a/content/renderer/mus/render_widget_window_tree_client_factory.h b/content/renderer/mus/render_widget_window_tree_client_factory.h
deleted file mode 100644
index 40f20b3..0000000
--- a/content/renderer/mus/render_widget_window_tree_client_factory.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-#ifndef CONTENT_RENDERER_MUS_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_
-#define CONTENT_RENDERER_MUS_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_
-
-namespace content {
-
-class ServiceManagerConnection;
-
-void CreateRenderWidgetWindowTreeClientFactory(
-    ServiceManagerConnection* connection);
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MUS_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_
diff --git a/content/renderer/mus/renderer_window_tree_client.cc b/content/renderer/mus/renderer_window_tree_client.cc
deleted file mode 100644
index 384141a..0000000
--- a/content/renderer/mus/renderer_window_tree_client.cc
+++ /dev/null
@@ -1,392 +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 "content/renderer/mus/renderer_window_tree_client.h"
-
-#include <map>
-
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/lazy_instance.h"
-#include "cc/base/switches.h"
-#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
-#include "components/viz/client/hit_test_data_provider.h"
-#include "components/viz/client/hit_test_data_provider_draw_quad.h"
-#include "components/viz/client/local_surface_id_provider.h"
-#include "components/viz/common/features.h"
-#include "content/renderer/mus/mus_embedded_frame.h"
-#include "content/renderer/mus/mus_embedded_frame_delegate.h"
-#include "content/renderer/render_frame_proxy.h"
-#include "services/ws/public/mojom/window_tree_constants.mojom.h"
-#include "ui/base/ui_base_features.h"
-
-namespace content {
-
-namespace {
-
-using ConnectionMap = std::map<int, RendererWindowTreeClient*>;
-base::LazyInstance<ConnectionMap>::Leaky g_connections =
-    LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-// static
-void RendererWindowTreeClient::CreateIfNecessary(int routing_id) {
-  if (!features::IsMultiProcessMash() || Get(routing_id))
-    return;
-  RendererWindowTreeClient* connection =
-      new RendererWindowTreeClient(routing_id);
-  g_connections.Get().insert(std::make_pair(routing_id, connection));
-}
-
-// static
-void RendererWindowTreeClient::Destroy(int routing_id) {
-  delete Get(routing_id);
-}
-
-// static
-RendererWindowTreeClient* RendererWindowTreeClient::Get(int routing_id) {
-  auto it = g_connections.Get().find(routing_id);
-  if (it != g_connections.Get().end())
-    return it->second;
-  return nullptr;
-}
-
-void RendererWindowTreeClient::Bind(
-    ws::mojom::WindowTreeClientRequest request,
-    mojom::RenderWidgetWindowTreeClientRequest
-        render_widget_window_tree_client_request) {
-  // Bind() may be called multiple times.
-  binding_.Close();
-  render_widget_window_tree_client_binding_.Close();
-
-  binding_.Bind(std::move(request));
-  render_widget_window_tree_client_binding_.Bind(
-      std::move(render_widget_window_tree_client_request));
-}
-
-std::unique_ptr<MusEmbeddedFrame>
-RendererWindowTreeClient::OnRenderFrameProxyCreated(
-    RenderFrameProxy* render_frame_proxy) {
-  auto iter = pending_frames_.find(render_frame_proxy->routing_id());
-  if (iter == pending_frames_.end())
-    return nullptr;
-
-  const base::UnguessableToken token = iter->second;
-  pending_frames_.erase(iter);
-  return CreateMusEmbeddedFrame(render_frame_proxy, token);
-}
-
-void RendererWindowTreeClient::SetVisible(bool visible) {
-  if (visible_ == visible)
-    return;
-
-  visible_ = visible;
-  if (tree_) {
-    tree_->SetWindowVisibility(GetAndAdvanceNextChangeId(), root_window_id_,
-                               visible);
-  }
-}
-
-void RendererWindowTreeClient::RequestLayerTreeFrameSink(
-    scoped_refptr<viz::ContextProvider> context_provider,
-    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-    LayerTreeFrameSinkCallback callback) {
-  DCHECK(pending_layer_tree_frame_sink_callback_.is_null());
-  if (tree_) {
-    RequestLayerTreeFrameSinkInternal(std::move(context_provider),
-                                      gpu_memory_buffer_manager,
-                                      std::move(callback));
-    return;
-  }
-
-  pending_context_provider_ = std::move(context_provider);
-  pending_gpu_memory_buffer_manager_ = gpu_memory_buffer_manager;
-  pending_layer_tree_frame_sink_callback_ = std::move(callback);
-}
-
-std::unique_ptr<MusEmbeddedFrame>
-RendererWindowTreeClient::CreateMusEmbeddedFrame(
-    MusEmbeddedFrameDelegate* delegate,
-    const base::UnguessableToken& token) {
-  std::unique_ptr<MusEmbeddedFrame> frame = base::WrapUnique<MusEmbeddedFrame>(
-      new MusEmbeddedFrame(this, delegate, ++next_window_id_, token));
-  embedded_frames_.insert(frame.get());
-  return frame;
-}
-
-RendererWindowTreeClient::RendererWindowTreeClient(int routing_id)
-    : routing_id_(routing_id),
-      binding_(this),
-      render_widget_window_tree_client_binding_(this) {}
-
-RendererWindowTreeClient::~RendererWindowTreeClient() {
-  g_connections.Get().erase(routing_id_);
-  DCHECK(embedded_frames_.empty());
-}
-
-void RendererWindowTreeClient::RequestLayerTreeFrameSinkInternal(
-    scoped_refptr<viz::ContextProvider> context_provider,
-    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-    LayerTreeFrameSinkCallback callback) {
-  viz::mojom::CompositorFrameSinkPtrInfo sink_info;
-  viz::mojom::CompositorFrameSinkRequest sink_request =
-      mojo::MakeRequest(&sink_info);
-  viz::mojom::CompositorFrameSinkClientPtr client;
-  viz::mojom::CompositorFrameSinkClientRequest client_request =
-      mojo::MakeRequest(&client);
-  cc::mojo_embedder::AsyncLayerTreeFrameSink::InitParams params;
-  params.gpu_memory_buffer_manager = gpu_memory_buffer_manager;
-  params.pipes.compositor_frame_sink_info = std::move(sink_info);
-  params.pipes.client_request = std::move(client_request);
-  params.enable_surface_synchronization = true;
-  if (features::IsVizHitTestingDrawQuadEnabled()) {
-    params.hit_test_data_provider =
-        std::make_unique<viz::HitTestDataProviderDrawQuad>(
-            true /* should_ask_for_child_region */,
-            true /* root_accepts_events */);
-  }
-  auto frame_sink =
-      std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
-          std::move(context_provider), nullptr /* worker_context_provider */,
-          &params);
-  tree_->AttachCompositorFrameSink(root_window_id_, std::move(sink_request),
-                                   std::move(client));
-  std::move(callback).Run(std::move(frame_sink));
-}
-
-void RendererWindowTreeClient::OnEmbeddedFrameDestroyed(
-    MusEmbeddedFrame* frame) {
-  embedded_frames_.erase(embedded_frames_.find(frame));
-}
-
-void RendererWindowTreeClient::Embed(uint32_t frame_routing_id,
-                                     const base::UnguessableToken& token) {
-  RenderFrameProxy* render_frame_proxy =
-      RenderFrameProxy::FromRoutingID(frame_routing_id);
-  if (!render_frame_proxy) {
-    pending_frames_[frame_routing_id] = token;
-    return;
-  }
-  render_frame_proxy->SetMusEmbeddedFrame(
-      CreateMusEmbeddedFrame(render_frame_proxy, token));
-}
-
-void RendererWindowTreeClient::OnEmbedFromToken(
-    const base::UnguessableToken& token,
-    ws::mojom::WindowDataPtr root,
-    int64_t display_id,
-    const base::Optional<viz::LocalSurfaceIdAllocation>&
-        local_surface_id_allocation) {
-  // Renderers don't use ScheduleEmbedForExistingClient(), so this path should
-  // never be hit.
-  NOTREACHED();
-}
-
-void RendererWindowTreeClient::DestroyFrame(uint32_t frame_routing_id) {
-  pending_frames_.erase(frame_routing_id);
-}
-
-void RendererWindowTreeClient::OnClientId(uint32_t client_id) {}
-
-void RendererWindowTreeClient::OnEmbed(
-    ws::mojom::WindowDataPtr root,
-    ws::mojom::WindowTreePtr tree,
-    int64_t display_id,
-    ws::Id focused_window_id,
-    bool drawn,
-    const base::Optional<viz::LocalSurfaceIdAllocation>&
-        local_surface_id_allocation) {
-  const bool is_reembed = tree_.is_bound();
-  if (is_reembed) {
-    for (MusEmbeddedFrame* frame : embedded_frames_)
-      frame->OnTreeWillChange();
-  }
-  root_window_id_ = root->window_id;
-
-  tree_ = std::move(tree);
-  tree_->SetWindowVisibility(GetAndAdvanceNextChangeId(), root_window_id_,
-                             visible_);
-  if (!is_reembed) {
-    for (MusEmbeddedFrame* frame : embedded_frames_)
-      frame->OnTreeAvailable();
-  }
-
-  if (!pending_layer_tree_frame_sink_callback_.is_null()) {
-    RequestLayerTreeFrameSinkInternal(
-        std::move(pending_context_provider_),
-        pending_gpu_memory_buffer_manager_,
-        std::move(pending_layer_tree_frame_sink_callback_));
-    pending_context_provider_ = nullptr;
-    pending_gpu_memory_buffer_manager_ = nullptr;
-    pending_layer_tree_frame_sink_callback_.Reset();
-  }
-}
-
-void RendererWindowTreeClient::OnEmbeddedAppDisconnected(ws::Id window_id) {
-  // TODO(sad): Embedded mus-client (oopif) is gone. Figure out what to do.
-}
-
-void RendererWindowTreeClient::OnUnembed(ws::Id window_id) {
-  // At this point all operations will fail. We don't delete this as it would
-  // mean all consumers have to null check (as would MusEmbeddedFrames).
-}
-
-void RendererWindowTreeClient::OnCaptureChanged(ws::Id new_capture_window_id,
-                                                ws::Id old_capture_window_id) {}
-
-void RendererWindowTreeClient::OnFrameSinkIdAllocated(
-    ws::Id window_id,
-    const viz::FrameSinkId& frame_sink_id) {
-  // When mus is not hosting viz FrameSinkIds come from the browser, so we
-  // ignore them here.
-  if (!features::IsMultiProcessMash())
-    return;
-
-  for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
-    if (embedded_frame->window_id_ == window_id) {
-      embedded_frame->delegate_->OnMusEmbeddedFrameSinkIdAllocated(
-          frame_sink_id);
-      return;
-    }
-  }
-}
-
-void RendererWindowTreeClient::OnTopLevelCreated(
-    uint32_t change_id,
-    ws::mojom::WindowDataPtr data,
-    int64_t display_id,
-    bool drawn,
-    const viz::LocalSurfaceIdAllocation& local_surface_id_allocation) {
-  NOTREACHED();
-}
-
-void RendererWindowTreeClient::OnWindowBoundsChanged(
-    ws::Id window_id,
-    const gfx::Rect& new_bounds,
-    ui::WindowShowState state,
-    const base::Optional<viz::LocalSurfaceIdAllocation>&
-        local_surface_id_allocation) {}
-
-void RendererWindowTreeClient::OnWindowTransformChanged(
-    ws::Id window_id,
-    const gfx::Transform& new_transform) {}
-
-void RendererWindowTreeClient::OnTransientWindowAdded(
-    ws::Id window_id,
-    ws::Id transient_window_id) {}
-
-void RendererWindowTreeClient::OnTransientWindowRemoved(
-    ws::Id window_id,
-    ws::Id transient_window_id) {}
-
-void RendererWindowTreeClient::OnWindowHierarchyChanged(
-    ws::Id window_id,
-    ws::Id old_parent_id,
-    ws::Id new_parent_id,
-    std::vector<ws::mojom::WindowDataPtr> windows) {}
-
-void RendererWindowTreeClient::OnWindowReordered(
-    ws::Id window_id,
-    ws::Id relative_window_id,
-    ws::mojom::OrderDirection direction) {}
-
-void RendererWindowTreeClient::OnWindowDeleted(ws::Id window_id) {
-  // See comments on OnUnembed() for why we do nothing here.
-}
-
-void RendererWindowTreeClient::OnWindowVisibilityChanged(ws::Id window_id,
-                                                         bool visible) {}
-
-void RendererWindowTreeClient::OnWindowDisplayChanged(ws::Id window_id,
-                                                      int64_t display_id) {}
-
-void RendererWindowTreeClient::OnWindowParentDrawnStateChanged(ws::Id window_id,
-                                                               bool drawn) {}
-
-void RendererWindowTreeClient::OnWindowSharedPropertyChanged(
-    ws::Id window_id,
-    const std::string& name,
-    const base::Optional<std::vector<uint8_t>>& new_data) {}
-
-void RendererWindowTreeClient::OnWindowInputEvent(
-    uint32_t event_id,
-    ws::Id window_id,
-    int64_t display_id,
-    std::unique_ptr<ui::Event> event,
-    bool matches_event_observer) {
-  NOTREACHED();
-}
-
-void RendererWindowTreeClient::OnObservedInputEvent(
-    std::unique_ptr<ui::Event> event) {
-  NOTREACHED();
-}
-
-void RendererWindowTreeClient::OnWindowFocused(ws::Id focused_window_id) {}
-
-void RendererWindowTreeClient::OnWindowCursorChanged(ws::Id window_id,
-                                                     ui::Cursor cursor) {}
-
-void RendererWindowTreeClient::OnDragDropStart(
-    const base::flat_map<std::string, std::vector<uint8_t>>& mime_data) {}
-
-void RendererWindowTreeClient::OnDragEnter(ws::Id window_id,
-                                           uint32_t event_flags,
-                                           const gfx::PointF& location_in_root,
-                                           const gfx::PointF& location,
-                                           uint32_t effect_bitmask,
-                                           OnDragEnterCallback callback) {}
-
-void RendererWindowTreeClient::OnDragOver(ws::Id window_id,
-                                          uint32_t event_flags,
-                                          const gfx::PointF& location_in_root,
-                                          const gfx::PointF& location,
-                                          uint32_t effect_bitmask,
-                                          OnDragOverCallback callback) {}
-
-void RendererWindowTreeClient::OnDragLeave(ws::Id window_id) {}
-
-void RendererWindowTreeClient::OnCompleteDrop(
-    ws::Id window_id,
-    uint32_t event_flags,
-    const gfx::PointF& location_in_root,
-    const gfx::PointF& location,
-    uint32_t effect_bitmask,
-    OnCompleteDropCallback callback) {}
-
-void RendererWindowTreeClient::OnPerformDragDropCompleted(
-    uint32_t change_id,
-    bool success,
-    uint32_t action_taken) {}
-
-void RendererWindowTreeClient::OnDragDropDone() {}
-
-void RendererWindowTreeClient::OnTopmostWindowChanged(
-    const std::vector<ws::Id>& topmost_ids) {}
-
-void RendererWindowTreeClient::OnChangeCompleted(uint32_t change_id,
-                                                 bool success) {
-  // Don't DCHECK success, as it's possible we'll try to do some operations
-  // after unembedded, which means all operations will fail. Additionally
-  // setting the window visibility may fail for the root frame (the browser
-  // controls the visibility of the root frame).
-}
-
-void RendererWindowTreeClient::RequestClose(ws::Id window_id) {}
-
-void RendererWindowTreeClient::GetScreenProviderObserver(
-    ws::mojom::ScreenProviderObserverAssociatedRequest observer) {}
-
-void RendererWindowTreeClient::OnOcclusionStatesChanged(
-    const base::flat_map<ws::Id, ws::mojom::OcclusionState>&
-        occlusion_changes) {}
-
-void RendererWindowTreeClient::CleanupGestureState(ws::Id window_id) {}
-
-void RendererWindowTreeClient::OnWindowResizeLoopStarted(ws::Id window_id) {}
-
-void RendererWindowTreeClient::OnWindowResizeLoopEnded(ws::Id window_id) {}
-
-}  // namespace content
diff --git a/content/renderer/mus/renderer_window_tree_client.h b/content/renderer/mus/renderer_window_tree_client.h
deleted file mode 100644
index 723e7fe..0000000
--- a/content/renderer/mus/renderer_window_tree_client.h
+++ /dev/null
@@ -1,239 +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 CONTENT_RENDERER_MUS_RENDERER_WINDOW_TREE_CLIENT_H_
-#define CONTENT_RENDERER_MUS_RENDERER_WINDOW_TREE_CLIENT_H_
-
-#include <map>
-#include <memory>
-
-#include "base/containers/flat_set.h"
-#include "base/macros.h"
-#include "base/unguessable_token.h"
-#include "components/viz/common/surfaces/local_surface_id.h"
-#include "content/common/render_widget_window_tree_client_factory.mojom.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "services/ws/common/types.h"
-#include "services/ws/public/mojom/window_tree.mojom.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace base {
-class UnguessableToken;
-}
-
-namespace cc {
-class LayerTreeFrameSink;
-}
-
-namespace gpu {
-class GpuMemoryBufferManager;
-}
-
-namespace viz {
-class ContextProvider;
-}
-
-namespace content {
-
-class MusEmbeddedFrame;
-class MusEmbeddedFrameDelegate;
-class RenderFrameProxy;
-
-// ws::mojom::WindowTreeClient implementation for RenderWidget. This lives and
-// operates on the renderer's main thread.
-class RendererWindowTreeClient : public ws::mojom::WindowTreeClient,
-                                 public mojom::RenderWidgetWindowTreeClient {
- public:
-  // Creates a RendererWindowTreeClient instance for the RenderWidget instance
-  // associated with |routing_id| (if one doesn't already exist). The instance
-  // self-destructs when the connection to mus is lost, or when the window is
-  // closed.
-  static void CreateIfNecessary(int routing_id);
-
-  // Destroys the client instance, if one exists. Otherwise, does nothing.
-  static void Destroy(int routing_id);
-
-  // Returns the RendererWindowTreeClient associated with |routing_id|. Returns
-  // nullptr if none exists.
-  // TODO(sky): make RenderWidget own RendererWindowTreeClient.
-  static RendererWindowTreeClient* Get(int routing_id);
-
-  void Bind(ws::mojom::WindowTreeClientRequest request,
-            mojom::RenderWidgetWindowTreeClientRequest
-                render_widget_window_tree_client_request);
-
-  // Called when a new RenderFrameProxy has been created. If there is a pending
-  // embedding ready, it's returned.
-  std::unique_ptr<MusEmbeddedFrame> OnRenderFrameProxyCreated(
-      RenderFrameProxy* render_frame_proxy);
-
-  // Sets the visibility of the client.
-  void SetVisible(bool visible);
-
-  using LayerTreeFrameSinkCallback =
-      base::OnceCallback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>;
-  void RequestLayerTreeFrameSink(
-      scoped_refptr<viz::ContextProvider> context_provider,
-      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-      LayerTreeFrameSinkCallback callback);
-
-  // Creates a new MusEmbeddedFrame. |token| is an UnguessableToken that was
-  // registered for an embedding with mus (specifically ws::mojom::WindowTree).
-  std::unique_ptr<MusEmbeddedFrame> CreateMusEmbeddedFrame(
-      MusEmbeddedFrameDelegate* mus_embedded_frame_delegate,
-      const base::UnguessableToken& token);
-
- private:
-  friend class MusEmbeddedFrame;
-
-  explicit RendererWindowTreeClient(int routing_id);
-  ~RendererWindowTreeClient() override;
-
-  void RequestLayerTreeFrameSinkInternal(
-      scoped_refptr<viz::ContextProvider> context_provider,
-      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-      LayerTreeFrameSinkCallback callback);
-
-  // Called from ~MusEmbeddedFrame to cleanup up internall mapping.
-  void OnEmbeddedFrameDestroyed(MusEmbeddedFrame* frame);
-
-  uint32_t GetAndAdvanceNextChangeId() { return ++next_change_id_; }
-
-  // mojom::RenderWidgetWindowTreeClient:
-  void Embed(uint32_t frame_routing_id,
-             const base::UnguessableToken& token) override;
-  void DestroyFrame(uint32_t frame_routing_id) override;
-
-  // ws::mojom::WindowTreeClient:
-  // Note: A number of the following are currently not-implemented. Some of
-  // these will remain unimplemented in the long-term. Some of the
-  // implementations would require some amount of refactoring out of
-  // RenderWidget and related classes (e.g. resize, input, ime etc.).
-  void OnClientId(uint32_t client_id) override;
-  void OnEmbed(ws::mojom::WindowDataPtr root,
-               ws::mojom::WindowTreePtr tree,
-               int64_t display_id,
-               ws::Id focused_window_id,
-               bool drawn,
-               const base::Optional<viz::LocalSurfaceIdAllocation>&
-                   local_surface_id_allocation) override;
-  void OnEmbedFromToken(const base::UnguessableToken& token,
-                        ws::mojom::WindowDataPtr root,
-                        int64_t display_id,
-                        const base::Optional<viz::LocalSurfaceIdAllocation>&
-                            local_surface_id_allocation) override;
-  void OnEmbeddedAppDisconnected(ws::Id window_id) override;
-  void OnUnembed(ws::Id window_id) override;
-  void OnCaptureChanged(ws::Id new_capture_window_id,
-                        ws::Id old_capture_window_id) override;
-  void OnFrameSinkIdAllocated(ws::Id window_id,
-                              const viz::FrameSinkId& frame_sink_id) override;
-  void OnTopLevelCreated(uint32_t change_id,
-                         ws::mojom::WindowDataPtr data,
-                         int64_t display_id,
-                         bool drawn,
-                         const viz::LocalSurfaceIdAllocation&
-                             local_surface_id_allocation) override;
-  void OnWindowBoundsChanged(
-      ws::Id window_id,
-      const gfx::Rect& new_bounds,
-      ui::WindowShowState state,
-      const base::Optional<viz::LocalSurfaceIdAllocation>&
-          local_surface_id_allocation) override;
-  void OnWindowTransformChanged(ws::Id window_id,
-                                const gfx::Transform& new_transform) override;
-  void OnTransientWindowAdded(ws::Id window_id,
-                              ws::Id transient_window_id) override;
-  void OnTransientWindowRemoved(ws::Id window_id,
-                                ws::Id transient_window_id) override;
-  void OnWindowHierarchyChanged(
-      ws::Id window_id,
-      ws::Id old_parent_id,
-      ws::Id new_parent_id,
-      std::vector<ws::mojom::WindowDataPtr> windows) override;
-  void OnWindowReordered(ws::Id window_id,
-                         ws::Id relative_window_id,
-                         ws::mojom::OrderDirection direction) override;
-  void OnWindowDeleted(ws::Id window_id) override;
-  void OnWindowVisibilityChanged(ws::Id window_id, bool visible) override;
-  void OnWindowDisplayChanged(ws::Id window_id, int64_t display_id) override;
-  void OnWindowParentDrawnStateChanged(ws::Id window_id, bool drawn) override;
-  void OnWindowSharedPropertyChanged(
-      ws::Id window_id,
-      const std::string& name,
-      const base::Optional<std::vector<uint8_t>>& new_data) override;
-  void OnWindowInputEvent(uint32_t event_id,
-                          ws::Id window_id,
-                          int64_t display_id,
-                          std::unique_ptr<ui::Event> event,
-                          bool matches_event_observer) override;
-  void OnObservedInputEvent(std::unique_ptr<ui::Event> event) override;
-  void OnWindowFocused(ws::Id focused_window_id) override;
-  void OnWindowCursorChanged(ws::Id window_id, ui::Cursor cursor) override;
-  void OnDragDropStart(const base::flat_map<std::string, std::vector<uint8_t>>&
-                           mime_data) override;
-  void OnDragEnter(ws::Id window_id,
-                   uint32_t event_flags,
-                   const gfx::PointF& location_in_root,
-                   const gfx::PointF& location,
-                   uint32_t effect_bitmask,
-                   OnDragEnterCallback callback) override;
-  void OnDragOver(ws::Id window_id,
-                  uint32_t event_flags,
-                  const gfx::PointF& location_in_root,
-                  const gfx::PointF& location,
-                  uint32_t effect_bitmask,
-                  OnDragOverCallback callback) override;
-  void OnDragLeave(ws::Id window_id) override;
-  void OnCompleteDrop(ws::Id window_id,
-                      uint32_t event_flags,
-                      const gfx::PointF& location_in_root,
-                      const gfx::PointF& location,
-                      uint32_t effect_bitmask,
-                      OnCompleteDropCallback callback) override;
-  void OnPerformDragDropCompleted(uint32_t change_id,
-                                  bool success,
-                                  uint32_t action_taken) override;
-  void OnDragDropDone() override;
-  void OnTopmostWindowChanged(const std::vector<ws::Id>& topmost_ids) override;
-  void OnChangeCompleted(uint32_t change_id, bool success) override;
-  void RequestClose(ws::Id window_id) override;
-  void GetScreenProviderObserver(
-      ws::mojom::ScreenProviderObserverAssociatedRequest observer) override;
-  void OnOcclusionStatesChanged(
-      const base::flat_map<ws::Id, ws::mojom::OcclusionState>&
-          occlusion_changes) override;
-  void CleanupGestureState(ws::Id window_id) override;
-  void OnWindowResizeLoopStarted(ws::Id window_id) override;
-  void OnWindowResizeLoopEnded(ws::Id window_id) override;
-
-  const int routing_id_;
-  ws::Id root_window_id_ = 0u;
-  bool visible_ = false;
-  scoped_refptr<viz::ContextProvider> pending_context_provider_;
-  gpu::GpuMemoryBufferManager* pending_gpu_memory_buffer_manager_ = nullptr;
-  LayerTreeFrameSinkCallback pending_layer_tree_frame_sink_callback_;
-  ws::mojom::WindowTreePtr tree_;
-  mojo::Binding<ws::mojom::WindowTreeClient> binding_;
-  mojo::Binding<mojom::RenderWidgetWindowTreeClient>
-      render_widget_window_tree_client_binding_;
-  ws::ClientSpecificId next_window_id_ = 0;
-  uint32_t next_change_id_ = 0;
-
-  // Set of MusEmbeddedFrames. They are owned by the corresponding
-  // RenderFrameProxy.
-  base::flat_set<MusEmbeddedFrame*> embedded_frames_;
-
-  // Because RenderFrameProxy is created from an IPC message on a different
-  // pipe it's entirely possible Embed() may be called before the
-  // RenderFrameProxy is created. If Embed() is called before the
-  // RenderFrameProxy is created the WindowTreeClient is added here.
-  std::map<uint32_t, base::UnguessableToken> pending_frames_;
-
-  DISALLOW_COPY_AND_ASSIGN(RendererWindowTreeClient);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MUS_RENDERER_WINDOW_TREE_CLIENT_H_
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc
index 11a081b..f75a138 100644
--- a/content/renderer/pepper/pepper_graphics_2d_host.cc
+++ b/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -719,7 +719,7 @@
     *release_callback = viz::SingleReleaseCallback::Create(
         base::BindOnce(&ReleaseTextureCallback, this->AsWeakPtr(),
                        main_thread_context_, size, gpu_mailbox));
-    *transferable_resource = viz::TransferableResource::MakeGLOverlay(
+    *transferable_resource = viz::TransferableResource::MakeGL(
         std::move(gpu_mailbox), GL_LINEAR, texture_target,
         std::move(out_sync_token), size, overlays_supported);
     transferable_resource->format = format;
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.cc b/content/renderer/pepper/ppb_graphics_3d_impl.cc
index 85a1162..ef2861a 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -186,10 +186,9 @@
     if (use_image_chromium_)
       target = GL_TEXTURE_RECTANGLE_ARB;
 #endif
-    viz::TransferableResource resource =
-        viz::TransferableResource::MakeGLOverlay(taken_front_buffer_, GL_LINEAR,
-                                                 target, sync_token, size,
-                                                 is_overlay_candidate);
+    viz::TransferableResource resource = viz::TransferableResource::MakeGL(
+        taken_front_buffer_, GL_LINEAR, target, sync_token, size,
+        is_overlay_candidate);
     HostGlobals::Get()
         ->GetInstance(pp_instance())
         ->CommitTransferableResource(resource);
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index 04b0734..e2cbf60 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -46,14 +46,8 @@
 #include "third_party/blink/public/web/web_triggering_event_info.h"
 #include "third_party/blink/public/web/web_user_gesture_indicator.h"
 #include "third_party/blink/public/web/web_view.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/gfx/geometry/size_conversions.h"
 
-#if defined(USE_AURA)
-#include "content/renderer/mus/mus_embedded_frame.h"
-#include "content/renderer/mus/renderer_window_tree_client.h"
-#endif
-
 #if BUILDFLAG(ENABLE_PRINTING)
 // nogncheck because dependency on //printing is conditional upon
 // enable_basic_printing flags.
@@ -264,19 +258,6 @@
 
   pending_visual_properties_.screen_info =
       render_widget_->GetOriginalScreenInfo();
-
-#if defined(USE_AURA)
-  if (features::IsMultiProcessMash()) {
-    RendererWindowTreeClient* renderer_window_tree_client =
-        RendererWindowTreeClient::Get(render_widget_->routing_id());
-    // It's possible a MusEmbeddedFrame has already been scheduled for creation
-    // (that is, RendererWindowTreeClient::Embed() was called). Call to
-    // OnRenderFrameProxyCreated() to potentially get the MusEmbeddedFrame.
-    // OnRenderFrameProxyCreated() returns null if Embed() was not called.
-    mus_embedded_frame_ =
-        renderer_window_tree_client->OnRenderFrameProxyCreated(this);
-  }
-#endif
 }
 
 void RenderFrameProxy::ResendVisualProperties() {
@@ -516,16 +497,13 @@
 void RenderFrameProxy::OnViewChanged(
     const FrameMsg_ViewChanged_Params& params) {
   crashed_ = false;
-  // In mash the FrameSinkId comes from RendererWindowTreeClient.
-  if (!features::IsMultiProcessMash()) {
-    // The same ParentLocalSurfaceIdAllocator cannot provide LocalSurfaceIds for
-    // two different frame sinks, so recreate it here.
-    if (frame_sink_id_ != *params.frame_sink_id) {
-      parent_local_surface_id_allocator_ =
-          std::make_unique<viz::ParentLocalSurfaceIdAllocator>();
-    }
-    frame_sink_id_ = *params.frame_sink_id;
+  // The same ParentLocalSurfaceIdAllocator cannot provide LocalSurfaceIds for
+  // two different frame sinks, so recreate it here.
+  if (frame_sink_id_ != *params.frame_sink_id) {
+    parent_local_surface_id_allocator_ =
+        std::make_unique<viz::ParentLocalSurfaceIdAllocator>();
   }
+  frame_sink_id_ = *params.frame_sink_id;
 
   // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
   // changes.
@@ -661,13 +639,6 @@
   SynchronizeVisualProperties();
 }
 
-#if defined(USE_AURA)
-void RenderFrameProxy::SetMusEmbeddedFrame(
-    std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame) {
-  mus_embedded_frame_ = std::move(mus_embedded_frame);
-}
-#endif
-
 void RenderFrameProxy::SynchronizeVisualProperties() {
   if (!frame_sink_id_.is_valid() || crashed_)
     return;
@@ -726,15 +697,6 @@
                           pending_visual_properties_.screen_space_rect;
   bool visual_properties_changed = synchronized_props_changed || rect_changed;
 
-#if defined(USE_AURA)
-  if (rect_changed && mus_embedded_frame_) {
-    mus_embedded_frame_->SetWindowBounds(
-        parent_local_surface_id_allocator_
-            ->GetCurrentLocalSurfaceIdAllocation(),
-        gfx::Rect(local_frame_size()));
-  }
-#endif
-
   if (!visual_properties_changed)
     return;
 
@@ -772,10 +734,6 @@
 }
 
 void RenderFrameProxy::FrameDetached(DetachType type) {
-#if defined(USE_AURA)
-  mus_embedded_frame_.reset();
-#endif
-
   if (type == DetachType::kRemove) {
     // Let the browser process know this subframe is removed, so that it is
     // destroyed in its current process.
@@ -963,24 +921,6 @@
   return devtools_frame_token_;
 }
 
-#if defined(USE_AURA)
-void RenderFrameProxy::OnMusEmbeddedFrameSinkIdAllocated(
-    const viz::FrameSinkId& frame_sink_id) {
-  // RendererWindowTreeClient should only call this when mus is hosting viz.
-  DCHECK(features::IsMultiProcessMash());
-  // The same ParentLocalSurfaceIdAllocator cannot provide LocalSurfaceIds for
-  // two different frame sinks, so re-create it here.
-  if (frame_sink_id_ != frame_sink_id) {
-    parent_local_surface_id_allocator_ =
-        std::make_unique<viz::ParentLocalSurfaceIdAllocator>();
-  }
-  frame_sink_id_ = frame_sink_id;
-  // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
-  // changes.
-  ResendVisualProperties();
-}
-#endif
-
 cc::Layer* RenderFrameProxy::GetLayer() {
   return embedded_layer_.get();
 }
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h
index 0cb2499..21c1d77 100644
--- a/content/renderer/render_frame_proxy.h
+++ b/content/renderer/render_frame_proxy.h
@@ -24,10 +24,6 @@
 #include "third_party/blink/public/web/web_remote_frame_client.h"
 #include "url/origin.h"
 
-#if defined(USE_AURA)
-#include "content/renderer/mus/mus_embedded_frame_delegate.h"
-#endif
-
 namespace blink {
 struct FramePolicy;
 struct WebRect;
@@ -49,10 +45,6 @@
 struct FrameReplicationState;
 struct ResourceTimingInfo;
 
-#if defined(USE_AURA)
-class MusEmbeddedFrame;
-#endif
-
 // When a page's frames are rendered by multiple processes, each renderer has a
 // full copy of the frame tree. It has full RenderFrames for the frames it is
 // responsible for rendering and placeholder objects for frames rendered by
@@ -75,9 +67,6 @@
 // RenderFrame is created for it.
 class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
                                         public IPC::Sender,
-#if defined(USE_AURA)
-                                        public MusEmbeddedFrameDelegate,
-#endif
                                         public ChildFrameCompositor,
                                         public blink::WebRemoteFrameClient {
  public:
@@ -173,11 +162,6 @@
   // Returns the widget used for the local frame root.
   RenderWidget* render_widget() { return render_widget_; }
 
-#if defined(USE_AURA)
-  void SetMusEmbeddedFrame(
-      std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame);
-#endif
-
   void SynchronizeVisualProperties();
 
   const gfx::Rect& screen_space_rect() const {
@@ -289,12 +273,6 @@
   void OnSetHasReceivedUserGestureBeforeNavigation(bool value);
   void OnRenderFallbackContent() const;
 
-#if defined(USE_AURA)
-  // MusEmbeddedFrameDelegate
-  void OnMusEmbeddedFrameSinkIdAllocated(
-      const viz::FrameSinkId& frame_sink_id) override;
-#endif
-
   // ChildFrameCompositor:
   cc::Layer* GetLayer() override;
   void SetLayer(scoped_refptr<cc::Layer> layer,
@@ -349,10 +327,6 @@
   blink::FrameOcclusionState last_occlusion_state_ =
       blink::FrameOcclusionState::kUnknown;
 
-#if defined(USE_AURA)
-  std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame_;
-#endif
-
   // The layer used to embed the out-of-process content.
   scoped_refptr<cc::Layer> embedded_layer_;
 
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc
index 97f719d..84a7c79a 100644
--- a/content/renderer/render_process_impl.cc
+++ b/content/renderer/render_process_impl.cc
@@ -140,6 +140,10 @@
   SetV8FlagIfFeature(features::kWebAssemblyCodeGC, "--wasm-code-gc");
   SetV8FlagIfNotFeature(features::kWebAssemblyCodeGC, "--no-wasm-code-gc");
 
+  SetV8FlagIfFeature(features::kWebAssemblySimd, "--experimental-wasm-simd");
+  SetV8FlagIfNotFeature(features::kWebAssemblySimd,
+                        "--no-experimental-wasm-simd");
+
   if (base::FeatureList::IsEnabled(features::kWebAssemblyThreads)) {
     constexpr char kFlags[] =
         "--harmony-sharedarraybuffer "
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index d4c55a5..aea4d16 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -99,8 +99,6 @@
 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/peer_connection_tracker.h"
 #include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
-#include "content/renderer/mus/render_widget_window_tree_client_factory.h"
-#include "content/renderer/mus/renderer_window_tree_client.h"
 #include "content/renderer/net_info_helper.h"
 #include "content/renderer/p2p/socket_dispatcher.h"
 #include "content/renderer/render_frame_proxy.h"
@@ -143,7 +141,6 @@
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "services/ws/public/cpp/gpu/context_provider_command_buffer.h"
 #include "services/ws/public/cpp/gpu/gpu.h"
-#include "services/ws/public/mojom/constants.mojom.h"
 #include "skia/ext/skia_memory_dump_provider.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
 #include "third_party/blink/public/platform/web_cache.h"
@@ -161,7 +158,6 @@
 #include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/skia/include/core/SkGraphics.h"
 #include "ui/base/layout.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/display/display_switches.h"
 
@@ -738,10 +734,7 @@
       base::BindRepeating(&CreateSingleSampleMetricsProvider,
                           main_thread_runner(), GetConnector()));
 
-  gpu_ = ws::Gpu::Create(GetConnector(),
-                         features::IsMultiProcessMash()
-                             ? ws::mojom::kServiceName
-                             : mojom::kBrowserServiceName,
+  gpu_ = ws::Gpu::Create(GetConnector(), mojom::kBrowserServiceName,
                          GetIOTaskRunner());
 
   resource_dispatcher_.reset(new ResourceDispatcher());
@@ -777,11 +770,6 @@
 
   audio_output_ipc_factory_.emplace(GetIOTaskRunner());
 
-#if defined(USE_AURA)
-  if (features::IsMultiProcessMash())
-    CreateRenderWidgetWindowTreeClientFactory(GetServiceManagerConnection());
-#endif
-
   registry->AddInterface(base::Bind(&SharedWorkerFactoryImpl::Create),
                          base::ThreadTaskRunnerHandle::Get());
   registry->AddInterface(base::BindRepeating(CreateResourceUsageReporter,
@@ -933,17 +921,8 @@
   categorized_worker_pool_->Start(num_raster_threads);
 
   discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
-  if (features::IsMultiProcessMash()) {
-#if defined(USE_AURA)
-    GetServiceManagerConnection()->GetConnector()->BindInterface(
-        ws::mojom::kServiceName, &manager_ptr);
-#else
-    NOTREACHED();
-#endif
-  } else {
-    ChildThread::Get()->GetConnector()->BindInterface(
-        mojom::kBrowserServiceName, mojo::MakeRequest(&manager_ptr));
-  }
+  ChildThread::Get()->GetConnector()->BindInterface(
+      mojom::kBrowserServiceName, mojo::MakeRequest(&manager_ptr));
 
   discardable_shared_memory_manager_ = std::make_unique<
       discardable_memory::ClientDiscardableSharedMemoryManager>(
@@ -1910,31 +1889,6 @@
 
   params.client_name = client_name;
 
-#if defined(USE_AURA)
-  if (features::IsMultiProcessMash()) {
-    if (!RendererWindowTreeClient::Get(widget_routing_id)) {
-      std::move(callback).Run(nullptr);
-      return;
-    }
-    scoped_refptr<gpu::GpuChannelHost> channel = EstablishGpuChannelSync();
-    // If the channel could not be established correctly, then return null. This
-    // would cause the compositor to wait and try again at a later time.
-    if (!channel) {
-      std::move(callback).Run(nullptr);
-      return;
-    }
-    RendererWindowTreeClient::Get(widget_routing_id)
-        ->RequestLayerTreeFrameSink(
-            gpu_->CreateContextProvider(std::move(channel)),
-            GetGpuMemoryBufferManager(), std::move(callback));
-    frame_sink_provider_->RegisterRenderFrameMetadataObserver(
-        widget_routing_id,
-        std::move(render_frame_metadata_observer_client_request),
-        std::move(render_frame_metadata_observer_ptr));
-    return;
-  }
-#endif
-
   viz::mojom::CompositorFrameSinkRequest compositor_frame_sink_request =
       mojo::MakeRequest(&params.pipes.compositor_frame_sink_info);
   viz::mojom::CompositorFrameSinkClientPtr compositor_frame_sink_client;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index a950813..09cbfae 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1997,16 +1997,6 @@
   }
 #endif  // BUILDFLAG(USE_DEFAULT_RENDER_THEME)
 
-#if defined(OS_ANDROID)
-  if (renderer_prefs.use_custom_colors)
-    blink::SetFocusRingColor(renderer_prefs.focus_ring_color);
-
-  blink::SetMinimumStrokeWidthForFocusRing(
-      renderer_prefs.minimum_stroke_width_for_focus_ring);
-
-  blink::SetIsFocusRingOutset(renderer_prefs.is_focus_ring_outset);
-#endif
-
   if (webview() &&
       old_accept_languages != renderer_preferences_.accept_languages) {
     webview()->AcceptLanguagesChanged();
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index abbcf4b..d9077a5 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -129,10 +129,6 @@
 #include "third_party/skia/include/core/SkPixelRef.h"
 #endif  // defined(OS_POSIX)
 
-#if defined(USE_AURA)
-#include "content/renderer/mus/renderer_window_tree_client.h"
-#endif
-
 #if defined(OS_MACOSX)
 #include "content/renderer/text_input_client_observer.h"
 #endif
@@ -480,11 +476,6 @@
                                           ->NewRenderWidgetSchedulingState();
     render_widget_scheduling_state_->SetHidden(is_hidden_);
   }
-#if defined(USE_AURA)
-  RendererWindowTreeClient::CreateIfNecessary(routing_id_);
-  if (features::IsMultiProcessMash())
-    RendererWindowTreeClient::Get(routing_id_)->SetVisible(!is_hidden_);
-#endif
 
   if (routing_id_ != MSG_ROUTING_NONE)
     g_routing_id_widget_map.Get().emplace(routing_id_, this);
@@ -498,13 +489,6 @@
   // and RenderViewImpl are rationalized. Currently, too many unit and
   // browser tests delete a RenderWidget without correclty going through
   // the shutdown. https://crbug.com/545684
-
-#if defined(USE_AURA)
-  // It is possible for a RenderWidget to be destroyed before it was embedded
-  // in a mus window. The RendererWindowTreeClient will leak in such cases. So
-  // explicitly delete it here.
-  RendererWindowTreeClient::Destroy(routing_id_);
-#endif
 }
 
 // static
@@ -2518,14 +2502,8 @@
   // throttled acks are released in case frame production ceases.
   is_hidden_ = hidden;
 
-#if defined(USE_AURA)
-  if (features::IsMultiProcessMash())
-    RendererWindowTreeClient::Get(routing_id_)->SetVisible(!hidden);
-#endif
-
-  if (is_hidden_) {
+  if (is_hidden_)
     first_update_visual_state_after_hidden_ = true;
-  }
 
   if (render_widget_scheduling_state_)
     render_widget_scheduling_state_->SetHidden(hidden);
diff --git a/content/shell/browser/shell_devtools_bindings.cc b/content/shell/browser/shell_devtools_bindings.cc
index 3f05ffe7..a35734fc 100644
--- a/content/shell/browser/shell_devtools_bindings.cc
+++ b/content/shell/browser/shell_devtools_bindings.cc
@@ -163,8 +163,8 @@
   content::RenderFrameHost* frame = navigation_handle->GetRenderFrameHost();
   if (navigation_handle->IsInMainFrame()) {
     frontend_host_ = DevToolsFrontendHost::Create(
-        frame,
-        base::Bind(&ShellDevToolsBindings::HandleMessageFromDevToolsFrontend,
+        frame, base::BindRepeating(
+                   &ShellDevToolsBindings::HandleMessageFromDevToolsFrontend,
                    base::Unretained(this)));
     return;
   }
diff --git a/content/shell/browser/shell_permission_manager.cc b/content/shell/browser/shell_permission_manager.cc
index f521188..173d3234 100644
--- a/content/shell/browser/shell_permission_manager.cc
+++ b/content/shell/browser/shell_permission_manager.cc
@@ -62,10 +62,10 @@
     RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
-  callback.Run(IsWhitelistedPermissionType(permission)
-                   ? blink::mojom::PermissionStatus::GRANTED
-                   : blink::mojom::PermissionStatus::DENIED);
+    base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) {
+  std::move(callback).Run(IsWhitelistedPermissionType(permission)
+                              ? blink::mojom::PermissionStatus::GRANTED
+                              : blink::mojom::PermissionStatus::DENIED);
   return PermissionController::kNoPendingOperation;
 }
 
@@ -74,15 +74,15 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<
-        void(const std::vector<blink::mojom::PermissionStatus>&)>& callback) {
+    base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)>
+        callback) {
   std::vector<blink::mojom::PermissionStatus> result;
   for (const auto& permission : permissions) {
     result.push_back(IsWhitelistedPermissionType(permission)
                          ? blink::mojom::PermissionStatus::GRANTED
                          : blink::mojom::PermissionStatus::DENIED);
   }
-  callback.Run(result);
+  std::move(callback).Run(result);
   return PermissionController::kNoPendingOperation;
 }
 
@@ -125,7 +125,7 @@
     PermissionType permission,
     RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
   return PermissionController::kNoPendingOperation;
 }
 
diff --git a/content/shell/browser/shell_permission_manager.h b/content/shell/browser/shell_permission_manager.h
index 844939e..8547766 100644
--- a/content/shell/browser/shell_permission_manager.h
+++ b/content/shell/browser/shell_permission_manager.h
@@ -17,20 +17,19 @@
   ~ShellPermissionManager() override;
 
   // PermissionManager implementation.
-  int RequestPermission(
-      PermissionType permission,
-      RenderFrameHost* render_frame_host,
-      const GURL& requesting_origin,
-      bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
-      override;
+  int RequestPermission(PermissionType permission,
+                        RenderFrameHost* render_frame_host,
+                        const GURL& requesting_origin,
+                        bool user_gesture,
+                        base::OnceCallback<void(blink::mojom::PermissionStatus)>
+                            callback) override;
   int RequestPermissions(
       const std::vector<PermissionType>& permission,
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<
-          void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
+      base::OnceCallback<
+          void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
       override;
   void ResetPermission(PermissionType permission,
                        const GURL& requesting_origin,
@@ -47,7 +46,7 @@
       PermissionType permission,
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
+      base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
       override;
   void UnsubscribePermissionStatusChange(int subscription_id) override;
 
diff --git a/content/shell/browser/web_test/devtools_protocol_test_bindings.cc b/content/shell/browser/web_test/devtools_protocol_test_bindings.cc
index 0a8236a..b968b37 100644
--- a/content/shell/browser/web_test/devtools_protocol_test_bindings.cc
+++ b/content/shell/browser/web_test/devtools_protocol_test_bindings.cc
@@ -75,8 +75,9 @@
   if (frame->GetParent())
     return;
   frontend_host_ = DevToolsFrontendHost::Create(
-      frame, base::Bind(&DevToolsProtocolTestBindings::HandleMessageFromTest,
-                        base::Unretained(this)));
+      frame,
+      base::BindRepeating(&DevToolsProtocolTestBindings::HandleMessageFromTest,
+                          base::Unretained(this)));
 #endif
 }
 
diff --git a/content/shell/browser/web_test/web_test_content_browser_client.cc b/content/shell/browser/web_test/web_test_content_browser_client.cc
index 04149aa4..d0c3c392 100644
--- a/content/shell/browser/web_test/web_test_content_browser_client.cc
+++ b/content/shell/browser/web_test/web_test_content_browser_client.cc
@@ -311,7 +311,7 @@
 void WebTestContentBrowserClient::ExposeInterfacesToFrame(
     service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>*
         registry) {
-  registry->AddInterface(base::Bind(&BindWebTestHelper));
+  registry->AddInterface(base::BindRepeating(&BindWebTestHelper));
 }
 
 std::unique_ptr<LoginDelegate> WebTestContentBrowserClient::CreateLoginDelegate(
diff --git a/content/shell/browser/web_test/web_test_permission_manager.cc b/content/shell/browser/web_test/web_test_permission_manager.cc
index 919475e..1a00c6a 100644
--- a/content/shell/browser/web_test/web_test_permission_manager.cc
+++ b/content/shell/browser/web_test/web_test_permission_manager.cc
@@ -20,7 +20,7 @@
 
 struct WebTestPermissionManager::Subscription {
   PermissionDescription permission;
-  base::Callback<void(blink::mojom::PermissionStatus)> callback;
+  base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback;
   blink::mojom::PermissionStatus current_value;
 };
 
@@ -59,10 +59,10 @@
     RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  callback.Run(
+  std::move(callback).Run(
       GetPermissionStatus(permission, requesting_origin,
                           WebContents::FromRenderFrameHost(render_frame_host)
                               ->GetLastCommittedURL()
@@ -75,8 +75,8 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<
-        void(const std::vector<blink::mojom::PermissionStatus>&)>& callback) {
+    base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)>
+        callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   std::vector<blink::mojom::PermissionStatus> result;
@@ -90,7 +90,7 @@
         GetPermissionStatus(permission, requesting_origin, embedding_origin));
   }
 
-  callback.Run(result);
+  std::move(callback).Run(result);
   return PermissionController::kNoPendingOperation;
 }
 
@@ -151,7 +151,7 @@
     PermissionType permission,
     RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // If the request is from a worker, it won't have a RFH.
@@ -165,7 +165,7 @@
   auto subscription = std::make_unique<Subscription>();
   subscription->permission =
       PermissionDescription(permission, requesting_origin, embedding_origin);
-  subscription->callback = callback;
+  subscription->callback = std::move(callback);
   subscription->current_value =
       GetPermissionStatus(permission, subscription->permission.origin,
                           subscription->permission.embedding_origin);
@@ -217,7 +217,8 @@
 void WebTestPermissionManager::OnPermissionChanged(
     const PermissionDescription& permission,
     blink::mojom::PermissionStatus status) {
-  std::list<base::OnceClosure> callbacks;
+  std::vector<base::OnceClosure> callbacks;
+  callbacks.reserve(subscriptions_.size());
 
   for (SubscriptionsMap::iterator iter(&subscriptions_); !iter.IsAtEnd();
        iter.Advance()) {
diff --git a/content/shell/browser/web_test/web_test_permission_manager.h b/content/shell/browser/web_test/web_test_permission_manager.h
index d0eacae..dfff29f9 100644
--- a/content/shell/browser/web_test/web_test_permission_manager.h
+++ b/content/shell/browser/web_test/web_test_permission_manager.h
@@ -22,20 +22,19 @@
   ~WebTestPermissionManager() override;
 
   // PermissionManager overrides.
-  int RequestPermission(
-      PermissionType permission,
-      RenderFrameHost* render_frame_host,
-      const GURL& requesting_origin,
-      bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
-      override;
+  int RequestPermission(PermissionType permission,
+                        RenderFrameHost* render_frame_host,
+                        const GURL& requesting_origin,
+                        bool user_gesture,
+                        base::OnceCallback<void(blink::mojom::PermissionStatus)>
+                            callback) override;
   int RequestPermissions(
       const std::vector<PermissionType>& permission,
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<
-          void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
+      base::OnceCallback<
+          void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
       override;
   void ResetPermission(PermissionType permission,
                        const GURL& requesting_origin,
@@ -52,7 +51,7 @@
       PermissionType permission,
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
+      base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
       override;
   void UnsubscribePermissionStatusChange(int subscription_id) override;
 
diff --git a/content/shell/browser/web_test/web_test_push_messaging_service.cc b/content/shell/browser/web_test/web_test_push_messaging_service.cc
index 2d6a2d96..72b15b3d 100644
--- a/content/shell/browser/web_test/web_test_push_messaging_service.cc
+++ b/content/shell/browser/web_test/web_test_push_messaging_service.cc
@@ -61,16 +61,16 @@
     int render_frame_id,
     const PushSubscriptionOptions& options,
     bool user_gesture,
-    const RegisterCallback& callback) {
+    RegisterCallback callback) {
   SubscribeFromWorker(requesting_origin, service_worker_registration_id,
-                      options, callback);
+                      options, std::move(callback));
 }
 
 void WebTestPushMessagingService::SubscribeFromWorker(
     const GURL& requesting_origin,
     int64_t service_worker_registration_id,
     const PushSubscriptionOptions& options,
-    const RegisterCallback& callback) {
+    RegisterCallback callback) {
   blink::mojom::PermissionStatus permission_status =
       WebTestContentBrowserClient::Get()
           ->browser_context()
@@ -89,12 +89,14 @@
                               kAuthentication + base::size(kAuthentication));
 
     subscribed_service_worker_registration_ = service_worker_registration_id;
-    callback.Run("layoutTestRegistrationId", p256dh, auth,
-                 mojom::PushRegistrationStatus::SUCCESS_FROM_PUSH_SERVICE);
+    std::move(callback).Run(
+        "layoutTestRegistrationId", p256dh, auth,
+        mojom::PushRegistrationStatus::SUCCESS_FROM_PUSH_SERVICE);
   } else {
-    callback.Run("registration_id", std::vector<uint8_t>() /* p256dh */,
-                 std::vector<uint8_t>() /* auth */,
-                 mojom::PushRegistrationStatus::PERMISSION_DENIED);
+    std::move(callback).Run("registration_id",
+                            std::vector<uint8_t>() /* p256dh */,
+                            std::vector<uint8_t>() /* auth */,
+                            mojom::PushRegistrationStatus::PERMISSION_DENIED);
   }
 }
 
@@ -121,12 +123,12 @@
     const GURL& requesting_origin,
     int64_t service_worker_registration_id,
     const std::string& sender_id,
-    const UnregisterCallback& callback) {
+    UnregisterCallback callback) {
   ClearPushSubscriptionId(
       WebTestContentBrowserClient::Get()->browser_context(), requesting_origin,
       service_worker_registration_id,
-      base::Bind(
-          callback,
+      base::BindOnce(
+          std::move(callback),
           service_worker_registration_id ==
                   subscribed_service_worker_registration_
               ? mojom::PushUnregistrationStatus::SUCCESS_UNREGISTERED
diff --git a/content/shell/browser/web_test/web_test_push_messaging_service.h b/content/shell/browser/web_test/web_test_push_messaging_service.h
index 2154c0c..88fd599 100644
--- a/content/shell/browser/web_test/web_test_push_messaging_service.h
+++ b/content/shell/browser/web_test/web_test_push_messaging_service.h
@@ -30,11 +30,11 @@
                              int render_frame_id,
                              const PushSubscriptionOptions& options,
                              bool user_gesture,
-                             const RegisterCallback& callback) override;
+                             RegisterCallback callback) override;
   void SubscribeFromWorker(const GURL& requesting_origin,
                            int64_t service_worker_registration_id,
                            const PushSubscriptionOptions& options,
-                           const RegisterCallback& callback) override;
+                           RegisterCallback callback) override;
   void GetSubscriptionInfo(const GURL& origin,
                            int64_t service_worker_registration_id,
                            const std::string& sender_id,
@@ -45,7 +45,7 @@
                    const GURL& requesting_origin,
                    int64_t service_worker_registration_id,
                    const std::string& sender_id,
-                   const UnregisterCallback& callback) override;
+                   UnregisterCallback callback) override;
   void DidDeleteServiceWorkerRegistration(
       const GURL& origin,
       int64_t service_worker_registration_id) override;
diff --git a/content/shell/renderer/shell_content_renderer_client.cc b/content/shell/renderer/shell_content_renderer_client.cc
index 26b675fd..7baeed5 100644
--- a/content/shell/renderer/shell_content_renderer_client.cc
+++ b/content/shell/renderer/shell_content_renderer_client.cc
@@ -113,10 +113,10 @@
 
   auto registry = std::make_unique<service_manager::BinderRegistry>();
   registry->AddInterface<mojom::TestService>(
-      base::Bind(&CreateRendererTestService),
+      base::BindRepeating(&CreateRendererTestService),
       base::ThreadTaskRunnerHandle::Get());
   registry->AddInterface<mojom::PowerMonitorTest>(
-      base::Bind(&PowerMonitorTestImpl::MakeStrongBinding),
+      base::BindRepeating(&PowerMonitorTestImpl::MakeStrongBinding),
       base::ThreadTaskRunnerHandle::Get());
   content::ChildThread::Get()
       ->GetServiceManagerConnection()
diff --git a/content/shell/renderer/web_test/web_test_render_frame_observer.cc b/content/shell/renderer/web_test/web_test_render_frame_observer.cc
index ae614472..807e772e 100644
--- a/content/shell/renderer/web_test/web_test_render_frame_observer.cc
+++ b/content/shell/renderer/web_test/web_test_render_frame_observer.cc
@@ -33,8 +33,9 @@
       test_runner->GetWebContentSettings());
   render_frame->GetWebFrame()->SetTextCheckClient(
       test_runner->GetWebTextCheckClient());
-  render_frame->GetAssociatedInterfaceRegistry()->AddInterface(base::Bind(
-      &WebTestRenderFrameObserver::BindRequest, base::Unretained(this)));
+  render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
+      base::BindRepeating(&WebTestRenderFrameObserver::BindRequest,
+                          base::Unretained(this)));
 }
 
 WebTestRenderFrameObserver::~WebTestRenderFrameObserver() = default;
diff --git a/content/shell/test_runner/accessibility_controller.cc b/content/shell/test_runner/accessibility_controller.cc
index 97a8d9d..501e842 100644
--- a/content/shell/test_runner/accessibility_controller.cc
+++ b/content/shell/test_runner/accessibility_controller.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/stl_util.h"
+#include "content/shell/test_runner/web_test_delegate.h"
 #include "content/shell/test_runner/web_view_test_proxy.h"
 #include "gin/handle.h"
 #include "gin/object_template_builder.h"
@@ -164,6 +165,14 @@
 void AccessibilityController::NotificationReceived(
     const blink::WebAXObject& target,
     const std::string& notification_name) {
+  web_view_test_proxy_->delegate()->PostTask(
+      base::BindOnce(&AccessibilityController::PostNotification,
+                     weak_factory_.GetWeakPtr(), target, notification_name));
+}
+
+void AccessibilityController::PostNotification(
+    const blink::WebAXObject& target,
+    const std::string& notification_name) {
   v8::Isolate* isolate = blink::MainThreadIsolate();
   v8::HandleScope handle_scope(isolate);
 
diff --git a/content/shell/test_runner/accessibility_controller.h b/content/shell/test_runner/accessibility_controller.h
index 9a74baea..14a26b7 100644
--- a/content/shell/test_runner/accessibility_controller.h
+++ b/content/shell/test_runner/accessibility_controller.h
@@ -35,6 +35,8 @@
   bool ShouldLogAccessibilityEvents();
   void NotificationReceived(const blink::WebAXObject& target,
                             const std::string& notification_name);
+  void PostNotification(const blink::WebAXObject& target,
+                        const std::string& notification_name);
 
  private:
   friend class AccessibilityControllerBindings;
diff --git a/content/shell/test_runner/test_plugin.cc b/content/shell/test_runner/test_plugin.cc
index 97d95e4b..cc1f3d5 100644
--- a/content/shell/test_runner/test_plugin.cc
+++ b/content/shell/test_runner/test_plugin.cc
@@ -319,9 +319,11 @@
     std::unique_ptr<viz::SingleReleaseCallback>* release_callback) {
   if (!content_changed_)
     return false;
+  gfx::Size size(rect_.width, rect_.height);
   if (!mailbox_.IsZero()) {
-    *resource = viz::TransferableResource::MakeGL(mailbox_, GL_LINEAR,
-                                                  GL_TEXTURE_2D, sync_token_);
+    *resource = viz::TransferableResource::MakeGL(
+        mailbox_, GL_LINEAR, GL_TEXTURE_2D, sync_token_, size,
+        false /* is_overlay_candidate */);
     // We pass ownership of the shared image to the callback.
     *release_callback = viz::SingleReleaseCallback::Create(
         base::BindOnce(&ReleaseSharedImage, context_provider_, mailbox_));
@@ -340,7 +342,7 @@
         base::BindOnce(&ReleaseSharedMemory, std::move(shared_bitmap_),
                        std::move(registration)));
   }
-  resource->size = gfx::Size(rect_.width, rect_.height);
+  resource->size = size;
   content_changed_ = false;
   return true;
 }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 93ce2151..6213fdf 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -815,6 +815,7 @@
     "../browser/generic_sensor/generic_sensor_browsertest.cc",
     "../browser/gpu/gpu_ipc_browsertests.cc",
     "../browser/gpu/in_process_gpu_thread_browsertests.cc",
+    "../browser/idle/idle_browsertest.cc",
     "../browser/indexed_db/indexed_db_browsertest.cc",
     "../browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc",
     "../browser/indexed_db/mock_browsertest_indexed_db_class_factory.h",
@@ -1430,7 +1431,6 @@
     "../browser/cocoa/system_hotkey_map_unittest.mm",
     "../browser/code_cache/generated_code_cache_unittest.cc",
     "../browser/compositor/reflector_impl_unittest.cc",
-    "../browser/compositor/software_browser_compositor_output_surface_unittest.cc",
     "../browser/cookie_store/cookie_store_manager_unittest.cc",
     "../browser/devtools/devtools_background_services_context_unittest.cc",
     "../browser/devtools/devtools_http_handler_unittest.cc",
@@ -2246,10 +2246,7 @@
     deps += [ "//ui/events:test_support" ]
   }
   if (!use_aura && !is_mac) {
-    sources -= [
-      "../browser/compositor/reflector_impl_unittest.cc",
-      "../browser/compositor/software_browser_compositor_output_surface_unittest.cc",
-    ]
+    sources -= [ "../browser/compositor/reflector_impl_unittest.cc" ]
   }
 
   if (!is_win && !is_mac) {
diff --git a/content/test/data/accessibility/event/add-child-expected-auralinux.txt b/content/test/data/accessibility/event/add-child-expected-auralinux.txt
new file mode 100644
index 0000000..16a68e3
--- /dev/null
+++ b/content/test/data/accessibility/event/add-child-expected-auralinux.txt
@@ -0,0 +1,2 @@
+CHILDREN-CHANGED index:2 CHILD:(role=ROLE_LIST_ITEM) role=ROLE_LIST ENABLED,SENSITIVE,SHOWING,VISIBLE
+
diff --git a/content/test/data/accessibility/event/add-child-expected-win.txt b/content/test/data/accessibility/event/add-child-expected-win.txt
index 5a2f0a84..9f149a0 100644
--- a/content/test/data/accessibility/event/add-child-expected-win.txt
+++ b/content/test/data/accessibility/event/add-child-expected-win.txt
@@ -1,3 +1,3 @@
-IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_LIST new_text={'<obj>' start=2 end=3}
-EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
-EVENT_OBJECT_REORDER on role=ROLE_SYSTEM_LIST
+EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_LIST SetSize=3
+EVENT_OBJECT_SHOW on <div> role=ROLE_SYSTEM_LISTITEM name="Item 3" PosInSet=3 SetSize=3
+IA2_EVENT_TEXT_INSERTED on <div> role=ROLE_SYSTEM_LIST SetSize=3 new_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/remove-child-expected-auralinux.txt b/content/test/data/accessibility/event/remove-child-expected-auralinux.txt
new file mode 100644
index 0000000..0ee020e8
--- /dev/null
+++ b/content/test/data/accessibility/event/remove-child-expected-auralinux.txt
@@ -0,0 +1,3 @@
+CHILDREN-CHANGED index:2 CHILD:(role=ROLE_LIST_ITEM) role=ROLE_LIST ENABLED,SENSITIVE,SHOWING,VISIBLE
+STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
+
diff --git a/content/test/data/accessibility/event/text-changed-contenteditable-expected-auralinux.txt b/content/test/data/accessibility/event/text-changed-contenteditable-expected-auralinux.txt
index 4419f72..ad7bf0a 100644
--- a/content/test/data/accessibility/event/text-changed-contenteditable-expected-auralinux.txt
+++ b/content/test/data/accessibility/event/text-changed-contenteditable-expected-auralinux.txt
@@ -1,3 +1,13 @@
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_PARAGRAPH EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_PARAGRAPH EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_PARAGRAPH EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_PARAGRAPH EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_PARAGRAPH EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_SECTION EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_SECTION EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_SECTION EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_SECTION EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_SECTION EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
 STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
 STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
 STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
diff --git a/content/test/data/accessibility/event/text-changed-expected-auralinux.txt b/content/test/data/accessibility/event/text-changed-expected-auralinux.txt
index 8fa35bd..d6e866e 100644
--- a/content/test/data/accessibility/event/text-changed-expected-auralinux.txt
+++ b/content/test/data/accessibility/event/text-changed-expected-auralinux.txt
@@ -1,3 +1,7 @@
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_ENTRY) role=ROLE_TEXT ENABLED,SENSITIVE,SHOWING,VISIBLE
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_ENTRY) role=ROLE_TEXT ENABLED,SENSITIVE,SHOWING,VISIBLE
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_PARAGRAPH ENABLED,SENSITIVE,SHOWING,VISIBLE
+CHILDREN-CHANGED index:0 CHILD:(role=ROLE_TEXT) role=ROLE_PARAGRAPH ENABLED,SENSITIVE,SHOWING,VISIBLE
 NAME-CHANGED:Modified Div role=ROLE_TEXT name='Modified Div' ENABLED,SENSITIVE,SHOWING,VISIBLE
 NAME-CHANGED:Modified Heading role=ROLE_TEXT name='Modified Heading' ENABLED,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
diff --git a/content/test/gpu/generate_new_expectations.py b/content/test/gpu/generate_new_expectations.py
new file mode 100755
index 0000000..8e940e5
--- /dev/null
+++ b/content/test/gpu/generate_new_expectations.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env vpython
+
+# 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 sys
+import gpu_project_config
+
+from gpu_tests import path_util
+
+path_util.SetupTelemetryPaths()
+
+from typ import arg_parser
+
+from telemetry.internal.browser import browser_options
+from telemetry.testing import serially_executed_browser_test_case
+from py_utils import discover
+
+def FindTestCase(test_name):
+  for start_dir in gpu_project_config.CONFIG.start_dirs:
+    modules_to_classes = discover.DiscoverClasses(
+        start_dir,
+        gpu_project_config.CONFIG.top_level_dir,
+        base_class=serially_executed_browser_test_case.
+        SeriallyExecutedBrowserTestCase)
+    for cl in modules_to_classes.values():
+      if cl.Name() == test_name:
+          return cl
+
+def main():
+  parser = arg_parser.ArgumentParser()
+  options, extra_args = parser.parse_known_args(sys.argv[1:])
+  assert options.tests, 'Please pass the test suite\'s name'
+  test_case = FindTestCase(options.tests[0])
+  assert test_case, 'Test \'%s\' is non-existant' % options.tests[0]
+  options = browser_options.BrowserFinderOptions()
+  parser = options.CreateParser(test_case.__doc__)
+  test_case.AddCommandlineArgs(parser)
+  finder_options, _ = parser.parse_args(extra_args)
+  # call to set class level arguments
+  _ = list(test_case.GenerateGpuTests(finder_options))
+  cls = test_case.GetExpectations()
+  new_expectations = cls.GenerateNewExpectationsFormat()
+  file_name = cls.__module__
+  file_name = file_name[file_name.find('.')+1:] + '.txt'
+  with open(file_name, 'w') as f:
+    f.write(new_expectations)
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py b/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py
index 0120aaf..f6fcbceb 100644
--- a/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py
+++ b/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py
@@ -520,3 +520,8 @@
           self.GetParsedCommandLineOptions().build_revision,
           SKIA_GOLD_INSTANCE)
     logging.error('View and triage untriaged images at %s', skia_url)
+
+  @classmethod
+  def GenerateGpuTests(cls, options):
+    del options
+    return []
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py b/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py
index 9468105..fa2dbf8 100644
--- a/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py
+++ b/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py
@@ -25,6 +25,7 @@
 from gpu_tests import pixel_integration_test
 from gpu_tests import pixel_test_pages
 from gpu_tests import webgl_conformance_integration_test
+from gpu_tests import webgl_test_util
 
 from py_utils import discover
 from typ import expectations_parser
@@ -100,6 +101,18 @@
     self.is_asan = is_asan
     self.webgl_conformance_version = webgl_version
     self.webgl2_only = False
+    self.url = 'https://www.google.com'
+    self.duration = 10
+    self.delay = 10
+    self.resolution = 100
+    self.fullscreen = False
+    self.underlay = False
+    self.logdir = '/tmp'
+    self.repeat = 1
+    self.outliers = 0
+    self.bypass_ipg = False
+    self.expected_vendor_id = 0
+    self.expected_device_id = 0
     self.browser_options = []
 
 
@@ -156,10 +169,10 @@
 
 def _checkTestExpectationsAreForExistingTests(
     test_class, mock_options, test_names=None):
-  expectations_file = test_class.ExpectationsFiles()[0]
   test_names = test_names or [
       args[0] for args in
       test_class.GenerateGpuTests(mock_options)]
+  expectations_file = test_class.ExpectationsFiles()[0]
   trie = {}
   for test in test_names:
     _trie = trie.setdefault(test[0], {})
@@ -188,24 +201,33 @@
 def _checkTestExpectationsForCollision(expectations, file_name):
   parser = expectations_parser.TaggedTestListParser(expectations)
   tests_to_exps = defaultdict(list)
-  conflicts_found = False
+  master_conflicts_found = False
   for exp in parser.expectations:
     if not exp.test.endswith('*'):
       tests_to_exps[exp.test].append(exp)
   error_msg = ''
   for pattern, exps in tests_to_exps.items():
-    if len(exps) > 1:
-      error_msg += ('\n\nFound conflicts for test %s in %s:\n' %
-                    (pattern, file_name))
+    conflicts_found = False
     for e1, e2 in itertools.combinations(exps, 2):
       if (e1.tags.issubset(_get_generic(e2.tags)) or
           e2.tags.issubset(_get_generic(e1.tags))):
-        conflicts_found = True
+        if not conflicts_found:
+          error_msg += ('\n\nFound conflicts for test %s in %s:\n' %
+                        (pattern, file_name))
+        master_conflicts_found = conflicts_found = True
         error_msg += ('  line %d conflicts with line %d\n' %
                       (e1.lineno, e2.lineno))
-  assert not conflicts_found, error_msg
+  assert not master_conflicts_found, error_msg
 
 
+def _CheckPatternIsValid(pattern):
+  if not '*' in pattern and not 'WebglExtension_' in pattern:
+    full_path = os.path.normpath(os.path.join(
+        webgl_test_util.conformance_path, pattern))
+    if not os.path.exists(full_path):
+      raise Exception('The WebGL conformance test path specified in ' +
+        'expectation does not exist: ' + full_path)
+
 def _testCheckTestExpectationsAreForExistingTests(expectations):
   options = MockArgs()
   expectations_file = tempfile.NamedTemporaryFile(delete=False)
@@ -292,6 +314,8 @@
     [ intel  ] a/b/c/d [ Failure ]
     [ amd mac ] a/b [ RetryOnFailure ]
     [ mac ] a/b [ Skip ]
+    [ amd mac ] a/b/c [ Failure ]
+    [ intel mac ] a/b/c [ Failure ]
     '''
     with self.assertRaises(AssertionError) as context:
       _checkTestExpectationsForCollision(test_expectations, 'test.txt')
@@ -307,6 +331,8 @@
       str(context.exception))
     self.assertIn('line 7 conflicts with line 8',
       str(context.exception))
+    self.assertNotIn("Found conflicts for test a/b/c in test.txt:",
+      str(context.exception))
 
   def testNoCollisionInTestExpectations(self):
     test_expectations = '''# tags: [ mac win linux ]
@@ -319,12 +345,17 @@
     _checkTestExpectationsForCollision(test_expectations, 'test.txt')
 
   def testNoCollisionsInGpuTestExpectations(self):
+    webgl_conformance_test_class = (
+        webgl_conformance_integration_test.WebGLConformanceIntegrationTest)
     for test_case in _FindTestCases():
       if 'gpu_tests.gpu_integration_test_unittest' not in test_case.__module__:
-        if test_case.ExpectationsFiles():
-          with open(test_case.ExpectationsFiles()[0]) as f:
-            _checkTestExpectationsForCollision(f.read(),
-            os.path.basename(f.name))
+        for i in xrange(1, 2 + (test_case == webgl_conformance_test_class)):
+          _ = list(test_case.GenerateGpuTests(
+              MockArgs(webgl_version=('%d.0.0' % i))))
+          if test_case.ExpectationsFiles():
+            with open(test_case.ExpectationsFiles()[0]) as f:
+              _checkTestExpectationsForCollision(f.read(),
+              os.path.basename(f.name))
 
   def testGpuTestExpectationsAreForExistingTests(self):
     options = MockArgs()
@@ -334,6 +365,19 @@
             and test_case.ExpectationsFiles()):
           _checkTestExpectationsAreForExistingTests(test_case, options)
 
+  def testWebglTestPathsExist(self):
+    webgl_test_class = (
+        webgl_conformance_integration_test.WebGLConformanceIntegrationTest)
+    for test_case in _FindTestCases():
+      if test_case == webgl_test_class:
+        for i in xrange(1, 3):
+          _ = list(test_case.GenerateGpuTests(
+              MockArgs(webgl_version='%d.0.0' % i)))
+          with open(test_case.ExpectationsFiles()[0], 'r') as f:
+            expectations = expectations_parser.TaggedTestListParser(f.read())
+            for exp in expectations.expectations:
+              _CheckPatternIsValid(exp.test)
+
   def testPixelTestsExpectationsAreForExistingTests(self):
     pixel_test_names = []
     for _, method in inspect.getmembers(
diff --git a/content/test/gpu/gpu_tests/gpu_test_expectations.py b/content/test/gpu/gpu_tests/gpu_test_expectations.py
index dd2b997..9339af0 100644
--- a/content/test/gpu/gpu_tests/gpu_test_expectations.py
+++ b/content/test/gpu/gpu_tests/gpu_test_expectations.py
@@ -2,8 +2,10 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from collections import defaultdict
 from gpu_tests import test_expectations
 
+import inspect
 import re
 
 ANGLE_CONDITIONS = ['d3d9', 'd3d11', 'opengl', 'opengles', 'vulkan', 'no_angle']
@@ -211,3 +213,59 @@
         gpu_info.aux_attributes.get('passthrough_cmd_decoder', False):
       return 'passthrough'
     return 'no_passthrough'
+
+  def GenerateNewExpectationsFormat(self):
+    expectations = ''
+    expectations_lines = []
+
+    def _GenerateTestExpectation(exp, conditions, cond=''):
+      if not conditions:
+        line = ''
+        if exp.bug:
+          line += 'crbug.com/%d ' % exp.bug
+        if cond:
+          line += '[ ' + cond + '] '
+        line += exp.pattern + ' '
+        if exp.expectation == 'flaky':
+          line += '[ RetryOnFailure ]'
+        elif exp.expectation == 'fail':
+          line += '[ Failure ]'
+        else:
+          line += '[ Skip ]'
+        expectations_lines.append(line)
+      else:
+        if conditions[0]:
+          for c in conditions[0]:
+            _GenerateTestExpectation(exp, conditions[1:], cond + c + ' ')
+        else:
+          _GenerateTestExpectation(exp, [], cond)
+
+    conditions_by_type = {
+        member: set() for member, attr in inspect.getmembers(
+            self.expectations[0]) if type(attr) == list}
+    for exp in self.expectations:
+      _conds = defaultdict(set)
+      for member, attr in inspect.getmembers(exp):
+        if member in conditions_by_type:
+          tags = []
+          for tag in attr:
+            if isinstance(tag, tuple):
+              try:
+                int(tag[1])
+                tags.append('%s-0x%x' % tag)
+              except Exception:
+                tags.append('%s-%s' % tag)
+            else:
+              tags.append(tag)
+          tags = [t.lower().replace(' ', '-').replace('_', '-')  for t in tags]
+          key = 'gpu_conditions' if member == 'device_id_conditions' else member
+          _conds[key].update(tags)
+          conditions_by_type[key].update(tags)
+      exp_conditions = sorted(_conds.values(), key=lambda l: -len(l))
+      _GenerateTestExpectation(exp, exp_conditions)
+    for _, tags in conditions_by_type.items():
+      if not tags:
+        continue
+      expectations += '# tags: [ %s ]\n' % ' '.join(tags)
+    expectations += '\n' + '\n'.join(expectations_lines) + '\n'
+    return expectations
diff --git a/content/test/gpu/gpu_tests/test_expectations.py b/content/test/gpu/gpu_tests/test_expectations.py
index cf7d7bd2..3d038ee 100644
--- a/content/test/gpu/gpu_tests/test_expectations.py
+++ b/content/test/gpu/gpu_tests/test_expectations.py
@@ -132,6 +132,10 @@
       for p in url_prefixes:
         self._url_prefixes.append(p)
 
+  @property
+  def expectations(self):
+    return self._expectations
+
   def SetExpectations(self):
     """Called on creation. Override to set up custom expectations."""
     pass
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
new file mode 100644
index 0000000..d0e1716
--- /dev/null
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -0,0 +1,808 @@
+# tags: [ d3d11 no-angle vulkan opengl ]
+# tags: [ win highsierra mac linux sierra android mojave ]
+# tags: [ passthrough no-passthrough ]
+# tags: [ intel amd-0x699f nvidia-0x1cb3 amd-0x6613 amd
+#         qualcomm nvidia-0xfe9 nvidia nvidia-0xf02 intel-0xa2e ]
+# tags: [ debug ]
+
+
+# ===================================
+# Extension availability expectations
+# ===================================
+# It's expected that not all extensions will be available on all platforms.
+# Having a test listed here is not necessarily a problem.
+
+# Skip these, rather than expect them to fail, to speed up test
+# execution. The browser is restarted even after expected test
+# failures.
+[ win ] WebglExtension_WEBGL_compressed_texture_astc [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_astc [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_astc [ Skip ]
+[ win ] WebglExtension_WEBGL_compressed_texture_etc [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_etc [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_etc [ Skip ]
+[ win ] WebglExtension_WEBGL_compressed_texture_etc1 [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_etc1 [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_etc1 [ Skip ]
+[ win ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
+[ win ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+
+# Disabling all multiview checks temporarily while ANGLE side changes
+# get merged in.
+crbug.com/864524 [ win ] WebglExtension_OVR_multiview2 [ Skip ]
+crbug.com/864524 [ mac ] WebglExtension_OVR_multiview2 [ Skip ]
+crbug.com/864524 [ android ] WebglExtension_OVR_multiview2 [ Skip ]
+crbug.com/864524 [ linux ] WebglExtension_OVR_multiview2 [ Skip ]
+crbug.com/808744 [ android ] WebglExtension_EXT_disjoint_timer_query_webgl2 [ Skip ]
+crbug.com/849576 [ no-passthrough ] WebglExtension_KHR_parallel_shader_compile [ Skip ]
+crbug.com/945970 [ android ] WebglExtension_EXT_float_blend [ Skip ]
+
+# ========================
+# Conformance expectations
+# ========================
+
+# Failing new test
+crbug.com/874620 [ linux nvidia ] conformance2/glsl3/const-struct-from-array-as-function-parameter.html [ Failure ]
+crbug.com/874620 [ opengl win nvidia ] conformance2/glsl3/const-struct-from-array-as-function-parameter.html [ Failure ]
+
+# TODO(shrekshao): Remove the following two Fail expectations
+# (draw-buffers and fs-color-type-mismatch-color-buffer-type)
+# after applying the new draw buffers validation
+crbug.com/927908 conformance2/rendering/draw-buffers.html [ Failure ]
+crbug.com/927908 conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html [ Failure ]
+
+# Too slow (take about one hour to run)
+crbug.com/619403 deqp/functional/gles3/builtinprecision/* [ Skip ]
+
+# Timing out on multiple platforms right now.
+crbug.com/757097 conformance/glsl/bugs/sampler-array-struct-function-arg.html [ Skip ]
+
+# Flakes heavily on many OpenGL configurations
+crbug.com/832238 [ no-angle ] conformance2/transform_feedback/too-small-buffers.html [ Failure ]
+
+# Failing on NVIDIA OpenGL, but fixed in latest driver
+# TODO(http://crbug.com/887241): Upgrade the drivers on the bots.
+crbug.com/772651 [ linux nvidia ] conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html [ Failure ]
+crbug.com/772651 [ android nvidia ] conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html [ Failure ]
+crbug.com/772651 [ nvidia ] conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html [ Failure ]
+
+# This test needs to be rewritten to measure its expected
+# performance; it's currently too flaky even on release bots.
+crbug.com/735483 conformance/rendering/texture-switch-performance.html [ Skip ]
+crbug.com/735483 conformance2/rendering/texture-switch-performance.html [ Skip ]
+
+# Nvidia bugs fixed in latest driver
+# TODO(http://crbug.com/887241): Upgrade the drivers on the bots.
+crbug.com/798117 [ vulkan win nvidia ] conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html [ Failure ]
+crbug.com/798117 [ linux nvidia ] conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html [ Failure ]
+crbug.com/792210 [ nvidia ] conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html [ Failure ]
+
+# Windows only.
+crbug.com/736926 [ win ] conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ]
+crbug.com/2291 [ win ] conformance2/rendering/framebuffer-texture-changing-base-level.html [ Failure ]
+crbug.com/3033 [ win no-passthrough ] conformance2/textures/misc/generate-mipmap-with-large-base-level.html [ Failure ]
+crbug.com/1465 [ win ] conformance2/glsl3/tricky-loop-conditions.html [ Failure ]
+crbug.com/951628 [ win no-passthrough ] conformance/rendering/blending.html [ Failure ]
+
+# Win / NVidia
+crbug.com/631317 [ d3d11 win nvidia ] deqp/functional/gles3/fbomultisample* [ RetryOnFailure ]
+crbug.com/679639 [ d3d11 win nvidia ] conformance2/rendering/draw-with-integer-texture-base-level.html [ Failure ]
+crbug.com/735464 [ d3d11 win nvidia ] deqp/functional/gles3/textureshadow/* [ RetryOnFailure ]
+crbug.com/907544 [ vulkan win passthrough nvidia ] conformance/uniforms/uniform-default-values.html [ RetryOnFailure ]
+crbug.com/945877 [ win passthrough ] conformance/attribs/gl-disabled-vertex-attrib.html [ Failure ]
+crbug.com/945877 [ linux passthrough ] conformance/attribs/gl-disabled-vertex-attrib.html [ Failure ]
+
+# Win / NVIDIA Quadro P400 / D3D11 flaky failures
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/data/gles3/shaders/functions.html [ Failure ]
+crbug.com/921052 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/framebufferblit/depth_stencil.html [ RetryOnFailure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html [ Failure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html [ Failure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html [ Failure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html [ Failure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_interleaved_lines.html [ Failure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html [ Failure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_separate_lines.html [ Failure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_separate_triangles.html [ Failure ]
+crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/interpolation_flat.html [ Failure ]
+crbug.com/728670 [ d3d11 win nvidia-0x1cb3 ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
+crbug.com/728670 [ d3d11 win nvidia-0x1cb3 ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ]
+crbug.com/728670 [ d3d11 win nvidia-0x1cb3 ] conformance2/textures/video/* [ RetryOnFailure ]
+crbug.com/728670 [ d3d11 win nvidia-0x1cb3 ] conformance2/textures/image_bitmap_from_video/* [ RetryOnFailure ]
+crbug.com/728670 [ d3d11 win nvidia-0x1cb3 ] conformance/extensions/oes-texture-half-float-with-video.html [ RetryOnFailure ]
+crbug.com/782254 [ d3d11 win nvidia-0x1cb3 ] conformance2/rendering/attrib-type-match.html [ RetryOnFailure ]
+
+# WIN / OpenGL / NVIDIA failures
+crbug.com/781668 [ opengl win nvidia-0x1cb3 ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html [ Failure ]
+crbug.com/921055 [ opengl win passthrough nvidia-0x1cb3 ] conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html [ RetryOnFailure ]
+crbug.com/715001 [ opengl win nvidia-0x1cb3 ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
+crbug.com/703779 [ opengl win nvidia-0x1cb3 ] conformance/textures/misc/texture-size.html [ Failure ]
+crbug.com/830046 [ opengl win passthrough nvidia ] conformance2/rendering/blitframebuffer-size-overflow.html [ Skip ]
+crbug.com/832238 [ opengl win no-passthrough nvidia ] conformance2/transform_feedback/switching-objects.html [ RetryOnFailure ]
+crbug.com/887578 [ opengl win passthrough nvidia ] deqp/data/gles3/shaders/conversions.html [ RetryOnFailure ]
+crbug.com/822733 [ opengl win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/* [ RetryOnFailure ]
+crbug.com/905003 [ opengl win passthrough nvidia ] conformance2/textures/misc/integer-cubemap-specification-order-bug.html [ Failure ]
+
+# Win / AMD
+
+# Recently many tests have become flaky on this configuration, returning
+# (72, 72, 72) when reading back pixels, rather than the expected values.
+# Going to try to skip the individual failing tests, rather than adding a
+# wildcard flaky suppression for all of the tests.
+crbug.com/844483 [ d3d11 win amd ] conformance2/renderbuffers/multisampled-renderbuffer-initialization.html [ Skip ]
+crbug.com/844483 [ d3d11 win amd ] conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html [ Skip ]
+crbug.com/844483 [ d3d11 win amd ] conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html [ Skip ]
+crbug.com/844483 [ d3d11 win amd ] conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html [ Skip ]
+crbug.com/844483 [ d3d11 win amd ] conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html [ Skip ]
+crbug.com/844483 [ d3d11 win amd ] conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html [ Skip ]
+crbug.com/844483 [ d3d11 win amd ] deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html [ Skip ]
+crbug.com/483282 [ d3d11 win amd ] conformance2/rendering/blitframebuffer-stencil-only.html [ Failure ]
+crbug.com/828984 [ d3d11 win amd ] deqp/functional/gles3/draw/draw_arrays_instanced.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] deqp/functional/gles3/draw/draw_elements.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] deqp/functional/gles3/draw/draw_range_elements.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] deqp/functional/gles3/draw/random.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] deqp/functional/gles3/samplerobject.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance/glsl/bugs/logic-inside-block-without-braces.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance/glsl/functions/glsl-function-mod-float.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance/renderbuffers/depth-renderbuffer-initialization.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance/renderbuffers/renderbuffer-initialization.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance2/glsl3/vector-dynamic-indexing.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html [ RetryOnFailure ]
+crbug.com/828984 [ d3d11 win amd ] conformance2/textures/misc/copy-texture-image-webgl-specific.html [ RetryOnFailure ]
+crbug.com/878780 [ win amd ] conformance2/textures/webgl_canvas/* [ RetryOnFailure ]
+
+# Recent AMD drivers seem to have a regression with 3D textures.
+crbug.com/2424 [ d3d11 win amd ] conformance2/textures/canvas_sub_rectangle/tex-3d-* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] conformance2/textures/image/tex-3d-* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] conformance2/textures/image_data/tex-3d-* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] conformance2/textures/misc/tex-unpack-params.html [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] conformance2/textures/video/tex-3d-* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] deqp/functional/gles3/shadertexturefunction/* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] deqp/functional/gles3/texturefiltering/3d_* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] deqp/functional/gles3/texturespecification/basic_teximage3d_3d_* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] deqp/functional/gles3/texturespecification/basic_texsubimage3d_* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] deqp/functional/gles3/texturespecification/teximage3d_pbo_3d* [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html [ Failure ]
+crbug.com/2424 [ d3d11 win amd ] deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html [ Failure ]
+
+# Have seen this time out. Think it may be because it's currently
+# the first test that runs in the shard, and the browser might not
+# be coming up correctly.
+crbug.com/687374 [ win amd-0x6613 ] deqp/functional/gles3/multisample.html [ RetryOnFailure ]
+
+# Failing on AMD RX 550
+crbug.com/3354 [ win amd-0x699f ] deqp/functional/gles3/fborender/shared_colorbuffer_02.html [ Skip ]
+
+# Win / Intel
+crbug.com/782317 [ d3d11 win intel ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
+crbug.com/945942 [ win passthrough intel ] conformance/uniforms/no-over-optimization-on-uniform-array-00.html [ RetryOnFailure ]
+crbug.com/620379 [ d3d11 win intel ] deqp/functional/gles3/lifetime.html [ RetryOnFailure ]
+crbug.com/614418 [ d3d11 win intel ] deqp/functional/gles3/textureformat/unsized_3d.html [ RetryOnFailure ]
+
+# This is an OpenGL driver bug on Intel platform and it is fixed in
+# Intel Driver 25.20.100.6444.
+# Case no-over-optimization-on-uniform-array-08 always fail if run
+# case gl-min-uniforms first.
+# Temporarily skip these two cases now.
+crbug.com/953243 [ opengl win passthrough intel ] conformance/limits/gl-min-uniforms.html [ Skip ]
+crbug.com/953243 [ opengl win passthrough intel ] conformance/uniforms/no-over-optimization-on-uniform-array-08.html [ Skip ]
+
+# This is an OpenGL driver bug on Intel platform and it is fixed in
+# Intel Driver 25.20.100.6444.
+# Case no-over-optimization-on-uniform-array-09 always fail if run
+# case biuDepthRange_001_to_002 first.
+# Temporarily skip these two cases now because this issue blocks
+# WEBGL_video_texture implementation.
+crbug.com/907195 [ opengl win passthrough intel ] conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html [ Skip ]
+crbug.com/907195 [ opengl win passthrough intel ] conformance/uniforms/no-over-optimization-on-uniform-array-09.html [ Skip ]
+
+# It's unfortunate that these suppressions need to be so broad, but it
+# looks like the D3D11 device can be lost spontaneously on this
+# configuration while running basically any test.
+crbug.com/628395 [ d3d11 win intel ] conformance/* [ RetryOnFailure ]
+crbug.com/628395 [ d3d11 win intel ] conformance2/* [ RetryOnFailure ]
+crbug.com/628395 [ d3d11 win intel ] deqp/* [ RetryOnFailure ]
+
+# Passthrough command decoder
+crbug.com/844349 [ passthrough ] conformance/misc/webgl-specific-stencil-settings.html [ Failure ]
+crbug.com/951628 [ passthrough ] conformance/rendering/blending.html [ Failure ]
+crbug.com/953120 [ passthrough ] conformance/programs/program-test.html [ Failure ]
+
+# Passthrough command decoder / OpenGL
+crbug.com/602688 [ opengl passthrough ] conformance2/misc/uninitialized-test-2.html [ Failure ]
+crbug.com/602688 [ opengl passthrough ] conformance2/rendering/draw-buffers-dirty-state-bug.html [ Failure ]
+crbug.com/602688 [ opengl passthrough ] conformance2/state/gl-get-calls.html [ Failure ]
+crbug.com/602688 [ opengl passthrough ] deqp/functional/gles3/integerstatequery.html [ Failure ]
+crbug.com/602688 [ opengl passthrough ] conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html [ Failure ]
+crbug.com/602688 [ opengl passthrough ] conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
+crbug.com/795030 [ opengl passthrough ] deqp/functional/gles3/shadercommonfunction.html [ Failure ]
+crbug.com/794341 [ opengl passthrough ] deqp/functional/gles3/shaderpackingfunction.html [ Failure ]
+crbug.com/814905 [ opengl passthrough ] conformance2/rendering/attrib-type-match.html [ Failure ]
+crbug.com/2994 [ opengl passthrough ] conformance2/textures/misc/copy-texture-image-same-texture.html [ Failure ]
+
+# Passthrough command decoder / OpenGL / Windows
+crbug.com/835364 [ opengl win passthrough ] deqp/functional/gles3/fbocompleteness.html [ Failure ]
+crbug.com/835364 [ opengl win passthrough ] conformance/renderbuffers/depth-renderbuffer-initialization.html [ RetryOnFailure ]
+
+# Passthrough command decoder / OpenGL / Intel
+crbug.com/602688 [ opengl passthrough intel ] conformance2/textures/video/tex-2d-rgb32f-rgb-float.html [ Failure ]
+crbug.com/602688 [ win opengl passthrough intel ] conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/602688 [ linux opengl passthrough intel ] conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/602688 [ opengl passthrough intel ] conformance/misc/uninitialized-test.html [ Failure ]
+crbug.com/602688 [ opengl passthrough intel ] conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
+crbug.com/602688 [ opengl passthrough intel ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Failure ]
+crbug.com/602688 [ opengl passthrough intel ] conformance/textures/misc/texture-attachment-formats.html [ Failure ]
+crbug.com/602688 [ opengl passthrough intel ] conformance/renderbuffers/framebuffer-state-restoration.html [ Failure ]
+
+# Passthrough command decoder / Windows / OpenGL / Intel
+# This case causes no-over-optimization-on-uniform-array fail.
+crbug.com/884210 [ opengl win passthrough intel ] conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html [ Skip ]
+crbug.com/854100 [ opengl win passthrough intel ] conformance/glsl/variables/gl-pointcoord.html [ RetryOnFailure ]
+crbug.com/2760 [ opengl win passthrough intel ] conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html [ Failure ]
+crbug.com/912579 [ opengl win passthrough intel ] conformance2/rendering/out-of-bounds-index-buffers-after-copying.html [ RetryOnFailure ]
+crbug.com/602688 [ opengl win passthrough intel ] conformance/glsl/constructors/glsl-construct-mat2.html [ Failure ]
+crbug.com/602688 [ opengl win passthrough intel ] conformance2/textures/misc/texture-npot.html [ Failure ]
+crbug.com/602688 [ opengl win passthrough intel ] conformance2/textures/misc/npot-video-sizing.html [ Failure ]
+crbug.com/602688 [ opengl win passthrough intel ] conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html [ Failure ]
+crbug.com/602688 [ opengl win passthrough intel ] conformance2/glsl3/vector-dynamic-indexing.html [ Failure ]
+crbug.com/2880 [ opengl win passthrough intel ] deqp/functional/gles3/shaderbuiltinvar.html [ Failure ]
+crbug.com/957631 [ opengl win passthrough intel ] conformance2/rendering/element-index-uint.html [ Failure ]
+
+# Passthrough command decoder / Linux / OpenGL / NVIDIA
+crbug.com/773861 [ opengl linux passthrough nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
+crbug.com/773861 [ opengl linux passthrough nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
+crbug.com/766918 [ opengl linux passthrough nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Failure ]
+crbug.com/766918 [ opengl linux passthrough nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ Failure ]
+crbug.com/766918 [ opengl linux passthrough nvidia ] conformance2/textures/image_bitmap_from_video/* [ RetryOnFailure ]
+crbug.com/793055 [ opengl linux passthrough nvidia ] deqp/functional/gles3/shaderoperator/common_functions_* [ Failure ]
+crbug.com/927407 [ opengl linux passthrough nvidia ] conformance/extensions/webgl-compressed-texture-s3tc.html [ RetryOnFailure ]
+
+# Passthrough command decoder / Linux / OpenGL / Intel
+crbug.com/2760 [ opengl linux passthrough intel ] conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html [ Failure ]
+crbug.com/2760 [ opengl linux passthrough intel ] conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html [ Failure ]
+crbug.com/2761 [ opengl linux passthrough intel ] conformance2/textures/misc/tex-mipmap-levels.html [ Failure ]
+crbug.com/950787 [ opengl linux passthrough intel ] conformance/extensions/webgl-compressed-texture-s3tc.html [ RetryOnFailure ]
+
+# Regressions in 10.12.4.
+crbug.com/705865 [ sierra intel ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
+crbug.com/705865 [ sierra intel ] conformance2/textures/misc/tex-mipmap-levels.html [ Failure ]
+crbug.com/870856 [ sierra amd ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
+
+# Flaky on 10.13 as well.
+crbug.com/870856 [ sierra amd ] conformance2/textures/misc/tex-mipmap-levels.html [ Failure ]
+crbug.com/870856 [ highsierra amd ] conformance2/textures/misc/tex-mipmap-levels.html [ RetryOnFailure ]
+
+# Regressions in 10.13
+crbug.com/774826 [ highsierra intel-0xa2e ] deqp/functional/gles3/fbocolorbuffer/tex2d_00.html [ Failure ]
+crbug.com/774826 [ mojave intel-0xa2e ] deqp/functional/gles3/fbocolorbuffer/tex2d_00.html [ Failure ]
+crbug.com/774826 [ highsierra intel-0xa2e ] deqp/functional/gles3/fboinvalidate/format_00.html [ Failure ]
+crbug.com/774826 [ mojave intel-0xa2e ] deqp/functional/gles3/fboinvalidate/format_00.html [ Failure ]
+crbug.com/774826 [ highsierra intel-0xa2e ] deqp/functional/gles3/framebufferblit/default_framebuffer_05.html [ Failure ]
+crbug.com/774826 [ mojave intel-0xa2e ] deqp/functional/gles3/framebufferblit/default_framebuffer_05.html [ Failure ]
+crbug.com/774827 [ highsierra nvidia-0xfe9 ] conformance2/glsl3/array-assign.html [ Failure ]
+crbug.com/774827 [ mojave nvidia-0xfe9 ] conformance2/glsl3/array-assign.html [ Failure ]
+crbug.com/774827 [ highsierra nvidia-0xfe9 ] deqp/functional/gles3/fborender/resize_03.html [ Failure ]
+crbug.com/774827 [ mojave nvidia-0xfe9 ] deqp/functional/gles3/fborender/resize_03.html [ Failure ]
+crbug.com/774827 [ highsierra nvidia-0xfe9 ] deqp/functional/gles3/shaderindexing/mat_00.html [ Failure ]
+crbug.com/774827 [ mojave nvidia-0xfe9 ] deqp/functional/gles3/shaderindexing/mat_00.html [ Failure ]
+crbug.com/774827 [ highsierra nvidia-0xfe9 ] deqp/functional/gles3/shaderindexing/mat_02.html [ Failure ]
+crbug.com/774827 [ mojave nvidia-0xfe9 ] deqp/functional/gles3/shaderindexing/mat_02.html [ Failure ]
+crbug.com/774827 [ highsierra nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html [ Failure ]
+crbug.com/774827 [ mojave nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html [ Failure ]
+crbug.com/905003 [ sierra intel-0xa2e ] conformance2/textures/misc/integer-cubemap-specification-order-bug.html [ Failure ]
+
+# Fails on multiple GPU types.
+crbug.com/844311 [ mac ] conformance/glsl/misc/fragcolor-fragdata-invariant.html [ Failure ]
+crbug.com/709351 [ mac ] conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html [ Failure ]
+crbug.com/630800 [ intel mac ] conformance2/rendering/framebuffer-completeness-unaffected.html [ Failure ]
+crbug.com/630800 [ nvidia mac ] conformance2/rendering/framebuffer-completeness-unaffected.html [ Failure ]
+crbug.com/630800 [ intel mac ] deqp/functional/gles3/fbocompleteness.html [ Failure ]
+crbug.com/630800 [ nvidia mac ] deqp/functional/gles3/fbocompleteness.html [ Failure ]
+crbug.com/811614 [ amd mac ] deqp/functional/gles3/negativeshaderapi.html [ Failure ]
+crbug.com/811614 [ intel mac ] deqp/functional/gles3/negativeshaderapi.html [ Failure ]
+
+# Mac Retina NVIDIA
+crbug.com/728271 [ mac nvidia-0xfe9 ] deqp/functional/gles3/shaderindexing/mat_01.html [ Failure ]
+crbug.com/728271 [ mac nvidia-0xfe9 ] deqp/functional/gles3/shaderindexing/tmp.html [ Failure ]
+crbug.com/641209 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fbomultisample* [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/default_framebuffer_04.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] conformance/attribs/gl-disabled-vertex-attrib.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] conformance/extensions/webgl-compressed-texture-size-limit.html [ RetryOnFailure ]
+crbug.com/923080 [ mac nvidia-0xfe9 ] conformance/ogles/GL/exp2/exp2_001_to_008.html [ RetryOnFailure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] conformance/programs/gl-bind-attrib-location-long-names-test.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] conformance/programs/gl-bind-attrib-location-test.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] conformance2/glsl3/loops-with-side-effects.html [ Failure ]
+crbug.com/483282 [ no-angle mac nvidia-0xfe9 ] conformance2/textures/misc/tex-input-validation.html [ Failure ]
+crbug.com/682834 [ mac nvidia-0xfe9 ] conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html [ RetryOnFailure ]
+crbug.com/922517 [ mac nvidia-0xfe9 ] conformance2/textures/canvas/tex-3d-rg16f-rg-float.html [ RetryOnFailure ]
+crbug.com/784817 [ mac nvidia-0xfe9 ] conformance/glsl/bugs/init-array-with-loop.html [ Failure ]
+crbug.com/716652 [ sierra nvidia-0xfe9 ] deqp/functional/gles3/draw/random.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_04.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_07.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_08.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_10.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_11.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_12.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_13.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_18.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_25.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_29.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_32.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_34.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/pixelbufferobject.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/negativevertexarrayapi.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/shaderindexing/varying.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html [ Failure ]
+crbug.com/614174 [ mac nvidia-0xfe9 ] deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fragmentoutput/array.fixed.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fragmentoutput/basic.fixed.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fragmentoutput/random_00.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fragmentoutput/random_01.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fragmentoutput/random_02.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fbocolorbuffer/clear.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fbocolorbuffer/tex2d_05.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fbocolorbuffer/tex3d_05.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fbocolorbuffer/texcube_05.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fbocolorbuffer/blend.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/draw/draw_arrays.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/draw/draw_arrays_instanced.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/draw/draw_elements.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/draw/draw_elements_instanced.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/draw/draw_range_elements.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/fboinvalidate/format_02.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/negativeshaderapi.html [ Failure ]
+crbug.com/483282 [ mac nvidia-0xfe9 ] deqp/functional/gles3/vertexarrays/multiple_attributes.output.html [ RetryOnFailure ]
+crbug.com/654187 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_28.html [ Failure ]
+crbug.com/654187 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_30.html [ Failure ]
+crbug.com/654187 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_31.html [ Failure ]
+crbug.com/654187 [ mac nvidia-0xfe9 ] deqp/functional/gles3/framebufferblit/conversion_33.html [ Failure ]
+crbug.com/795052 [ mac nvidia-0xfe9 ] conformance2/uniforms/draw-with-uniform-blocks.html [ Failure ]
+crbug.com/911772 [ mac nvidia-0xfe9 ] conformance2/glsl3/compound-assignment-type-combination.html [ RetryOnFailure ]
+crbug.com/911772 [ mac nvidia-0xfe9 ] conformance2/query/occlusion-query.html [ RetryOnFailure ]
+crbug.com/911772 [ mac nvidia-0xfe9 ] conformance2/state/gl-object-get-calls.html [ RetryOnFailure ]
+crbug.com/911772 [ mac nvidia-0xfe9 ] conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/911772 [ mac nvidia-0xfe9 ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
+crbug.com/911772 [ mac nvidia-0xfe9 ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html [ RetryOnFailure ]
+crbug.com/911772 [ mac nvidia-0xfe9 ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ]
+crbug.com/911772 [ mac nvidia-0xfe9 ] conformance2/textures/canvas/tex-3d-r16f-red-half_float.html [ RetryOnFailure ]
+crbug.com/929398 [ mac nvidia-0xfe9 ] conformance2/glsl3/tricky-loop-conditions.html [ Failure ]
+crbug.com/934556 [ mac nvidia-0xfe9 ] conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html [ RetryOnFailure ]
+crbug.com/952282 [ mac nvidia-0xfe9 ] conformance2/rendering/framebuffer-unsupported.html [ RetryOnFailure ]
+crbug.com/756537 [ mac nvidia ] deqp/functional/gles3/shaderoperator/* [ Failure ]
+crbug.com/907599 [ mac nvidia debug ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ]
+
+# Mac AMD
+# TODO(kbr): uncomment the following two exepectations after test
+# has been made more robust.
+# self.Fail('conformance/rendering/texture-switch-performance.html',
+#     ['mac', 'amd'], bug=735483)
+# self.Fail('conformance2/rendering/texture-switch-performance.html',
+#     ['mac', 'amd'], bug=735483)
+
+# The following two failures are a regression in the Mac AMD
+# OpenGL driver on 10.13.6 specifically. Unfortunately when the
+# tests fail, they fail three times in a row, so we must mark them
+# failing rather than flaky.
+crbug.com/870856 [ highsierra amd ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/array_interleaved_lines.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/array_interleaved_points.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/array_separate_lines.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/array_separate_points.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/array_separate_triangles.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/basic_types_separate_points.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/interpolation_centroid.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/interpolation_flat.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/interpolation_smooth.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/point_size.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/position.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/random_interleaved_lines.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/random_interleaved_points.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/random_separate_lines.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/random_separate_points.html [ Failure ]
+crbug.com/483282 [ sierra amd ] deqp/functional/gles3/transformfeedback/random_separate_triangles.html [ Failure ]
+crbug.com/751254 [ mac amd ] deqp/functional/gles3/shaderindexing/mat_00.html [ RetryOnFailure ]
+crbug.com/636648 [ mac amd ] deqp/functional/gles3/shaderindexing/mat_01.html [ RetryOnFailure ]
+crbug.com/644360 [ mac amd ] deqp/functional/gles3/shaderindexing/mat_02.html [ RetryOnFailure ]
+crbug.com/659871 [ mac amd ] deqp/functional/gles3/shaderindexing/tmp.html [ RetryOnFailure ]
+crbug.com/928989 [ mac amd ] deqp/functional/gles3/shaderindexing/varying.html [ RetryOnFailure ]
+
+# These seem to be provoking intermittent GPU process crashes on
+# the MacBook Pros with AMD GPUs.
+crbug.com/663601 [ mac amd ] deqp/functional/gles3/texturefiltering/* [ RetryOnFailure ]
+crbug.com/663601 [ mac amd ] deqp/functional/gles3/textureshadow/* [ RetryOnFailure ]
+crbug.com/679058 [ mac amd ] deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html [ RetryOnFailure ]
+crbug.com/642822 [ mac amd ] conformance2/rendering/clipping-wide-points.html [ Failure ]
+
+# Mac Intel
+crbug.com/886970 [ mac intel-0xa2e ] conformance/rendering/canvas-alpha-bug.html [ Failure ]
+crbug.com/678526 [ mac intel ] conformance2/rendering/framebuffer-texture-level1.html [ Failure ]
+crbug.com/679692 [ mac no-passthrough intel ] conformance2/textures/misc/angle-stuck-depth-textures.html [ Failure ]
+crbug.com/641209 [ mac intel ] deqp/functional/gles3/fbomultisample* [ Failure ]
+crbug.com/606074 [ mac intel ] deqp/functional/gles3/texturefiltering/2d_combinations_01.html [ Failure ]
+crbug.com/606074 [ mac intel ] deqp/functional/gles3/texturefiltering/cube_combinations_01.html [ Failure ]
+crbug.com/606074 [ mac intel ] deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html [ Failure ]
+crbug.com/606074 [ mac intel ] deqp/functional/gles3/texturefiltering/3d_combinations_06.html [ Failure ]
+crbug.com/606074 [ mac intel ] deqp/functional/gles3/texturefiltering/3d_combinations_07.html [ Failure ]
+crbug.com/606074 [ mac intel ] deqp/functional/gles3/texturefiltering/3d_combinations_08.html [ Failure ]
+crbug.com/658724 [ mac intel ] deqp/functional/gles3/framebufferblit/rect_03.html [ Failure ]
+crbug.com/658724 [ mac intel ] deqp/functional/gles3/framebufferblit/rect_04.html [ Failure ]
+crbug.com/658657 [ mac intel ] deqp/functional/gles3/texturespecification/random_teximage2d_2d.html [ Failure ]
+crbug.com/905004 [ mac intel ] deqp/functional/gles3/shadertexturefunction/texturelod.html [ Failure ]
+crbug.com/905004 [ mac intel ] deqp/functional/gles3/shadertexturefunction/texturegrad.html [ Failure ]
+crbug.com/905004 [ mac intel ] deqp/functional/gles3/shadertexturefunction/textureprojgrad.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html [ Failure ]
+crbug.com/665197 [ mac intel-0xa2e ] conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/658930 [ mac intel ] conformance2/textures/misc/integer-cubemap-texture-sampling.html [ Failure ]
+crbug.com/731877 [ mac intel-0xa2e ] conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html [ Failure ]
+crbug.com/782317 [ mac intel ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
+
+# Linux only.
+crbug.com/627525 [ linux ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/627525 [ linux ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ]
+crbug.com/627525 [ linux ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
+crbug.com/627525 [ linux ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/627525 [ linux ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ]
+crbug.com/905006 [ linux nvidia ] conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html [ Failure ]
+
+# Linux Multi-vendor failures.
+crbug.com/618447 [ linux amd ] deqp/functional/gles3/texturespecification/random_teximage2d_2d.html [ RetryOnFailure ]
+crbug.com/662644 [ linux amd ] conformance2/rendering/clipping-wide-points.html [ Failure ]
+
+# Linux NVIDIA
+# This test is flaky both with and without ANGLE.
+crbug.com/618447 [ linux nvidia ] deqp/functional/gles3/texturespecification/random_teximage2d_2d.html [ RetryOnFailure ]
+crbug.com/618447 [ linux nvidia ] deqp/functional/gles3/texturespecification/random_teximage2d_cube.html [ RetryOnFailure ]
+crbug.com/709351 [ linux nvidia ] conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html [ Failure ]
+crbug.com/905003 [ linux nvidia ] conformance2/textures/misc/integer-cubemap-specification-order-bug.html [ Failure ]
+crbug.com/680278 [ opengl linux nvidia ] conformance2/rendering/framebuffer-texture-level1.html [ Failure ]
+crbug.com/680282 [ linux nvidia-0xf02 ] conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/694354 [ linux no-passthrough nvidia ] conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/832238 [ linux no-passthrough nvidia ] conformance2/transform_feedback/switching-objects.html [ RetryOnFailure ]
+
+# Linux NVIDIA Quadro P400
+crbug.com/830046 [ linux passthrough nvidia-0x1cb3 ] conformance2/rendering/blitframebuffer-size-overflow.html [ Skip ]
+
+# Observed flaky on Swarmed bots. Some of these were directly
+# observed, some not. We can't afford any flakes on the tryservers
+# so mark them all flaky.
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/array_interleaved_lines.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/array_interleaved_points.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/array_separate_lines.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/array_separate_points.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/array_separate_triangles.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_separate_points.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/interpolation_centroid.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/interpolation_flat.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/interpolation_smooth.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/point_size.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/position.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_interleaved_lines.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_interleaved_points.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_separate_lines.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_separate_points.html [ RetryOnFailure ]
+crbug.com/780706 [ linux nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_separate_triangles.html [ RetryOnFailure ]
+crbug.com/906846 [ linux nvidia ] conformance2/rendering/canvas-resizing-with-pbo-bound.html [ RetryOnFailure ]
+
+# Linux NVIDIA Quadro P400, OpenGL backend
+crbug.com/715001 [ linux nvidia-0x1cb3 ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
+crbug.com/703779 [ opengl linux nvidia-0x1cb3 ] conformance/textures/misc/texture-size.html [ Failure ]
+crbug.com/703779 [ opengl linux nvidia-0x1cb3 ] conformance/extensions/webgl-compressed-texture-size-limit.html [ Failure ]
+crbug.com/703779 [ opengl linux nvidia-0x1cb3 ] conformance/textures/misc/texture-size-limit.html [ Failure ]
+crbug.com/703779 [ opengl linux nvidia-0x1cb3 ] deqp/functional/gles3/fbocompleteness.html [ Failure ]
+
+# Linux Intel
+crbug.com/950552 [ linux intel ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
+
+# Already fixed with Mesa 17.2.3
+crbug.com/905011 [ linux intel ] conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html [ Failure ]
+crbug.com/666384 [ linux intel ] deqp/functional/gles3/shadertexturefunction/texturesize.html [ Failure ]
+crbug.com/666384 [ linux intel ] conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html [ Failure ]
+
+# Already fixed with Mesa 17.1.6
+crbug.com/680675 [ linux intel ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ]
+
+# Linux AMD only.
+# It looks like AMD shader compiler rejects many valid ES3 semantics.
+crbug.com/844311 [ linux amd ] conformance/glsl/misc/fragcolor-fragdata-invariant.html [ Failure ]
+crbug.com/766776 [ linux amd ] conformance2/attribs/gl-vertex-attrib-normalized-int.html [ Failure ]
+crbug.com/483282 [ linux amd ] conformance/glsl/misc/shaders-with-invariance.html [ Failure ]
+crbug.com/709351 [ linux amd ] conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html [ Failure ]
+crbug.com/617290 [ linux amd ] deqp/functional/gles3/multisample.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/data/gles3/shaders/conversions.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/data/gles3/shaders/arrays.html [ Skip ]
+crbug.com/483282 [ linux amd ] deqp/data/gles3/shaders/qualification_order.html [ Skip ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/internalformatquery.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturestatequery.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/buffercopy.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/samplerobject.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shaderprecision_int.html [ Failure ]
+crbug.com/606114 [ linux amd ] deqp/functional/gles3/texturefiltering/3d* [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shadertexturefunction/texture.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shadertexturefunction/texturegrad.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html [ Failure ]
+crbug.com/694877 [ linux amd ] deqp/functional/gles3/vertexarrays/single_attribute.first.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/negativetextureapi.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/transformfeedback/array_separate* [ Failure ]
+crbug.com/483282 [ linux no-passthrough amd ] conformance2/misc/uninitialized-test-2.html [ Failure ]
+crbug.com/483282 [ linux amd ] conformance2/reading/read-pixels-from-fbo-test.html [ Failure ]
+crbug.com/634525 [ linux amd ] conformance2/rendering/blitframebuffer-filter-srgb.html [ Failure ]
+crbug.com/662644 [ linux amd ] conformance2/rendering/blitframebuffer-outside-readbuffer.html [ Failure ]
+crbug.com/295792 [ linux amd ] conformance2/renderbuffers/framebuffer-texture-layer.html [ Failure ]
+crbug.com/483282 [ linux amd ] conformance2/textures/misc/tex-mipmap-levels.html [ Failure ]
+crbug.com/483282 [ linux amd ] conformance2/textures/misc/copy-texture-image-luma-format.html [ Failure ]
+crbug.com/899754 [ linux amd ] conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html [ Failure ]
+crbug.com/911216 [ linux no-passthrough amd ] conformance2/textures/misc/copy-texture-image-same-texture.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/basic_copyteximage2d.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/texturespecification/texstorage3d_format_size.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/draw/* [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/fbomultisample* [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/fbocompleteness.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/textureshadow/* [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shadermatrix/pre_decrement.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_04.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_07.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_08.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_10.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_11.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_12.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_13.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_18.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_25.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_28.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_29.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_30.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_31.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_32.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_33.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_34.html [ Failure ]
+crbug.com/658832 [ linux amd ] deqp/functional/gles3/framebufferblit/default_framebuffer_00.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shaderoperator/unary_operator_01.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/shaderoperator/unary_operator_02.html [ Failure ]
+crbug.com/483282 [ linux amd ] conformance2/glsl3/vector-dynamic-indexing.html [ Failure ]
+crbug.com/483282 [ no-angle linux amd ] conformance2/reading/read-pixels-pack-parameters.html [ Failure ]
+crbug.com/483282 [ no-angle linux amd ] conformance2/textures/misc/tex-unpack-params.html [ Failure ]
+
+# TODO(kbr): re-enable after next conformance roll. crbug.com/736499
+# crbug.com/633022 [ linux amd ] conformance2/extensions/ext-color-buffer-float.html [ Failure ]
+crbug.com/655147 [ linux no-passthrough amd ] conformance2/rendering/blitframebuffer-filter-outofbounds.html [ Failure ]
+crbug.com/705865 [ linux amd ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
+crbug.com/705865 [ linux amd ] conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html [ Failure ]
+
+# Uniform buffer related failures
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/uniformbuffers/single_struct_array.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/uniformbuffers/single_nested_struct.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/uniformbuffers/multi_basic_types.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/uniformbuffers/multi_nested_struct.html [ Failure ]
+crbug.com/483282 [ linux amd ] deqp/functional/gles3/uniformbuffers/random.html [ Failure ]
+crbug.com/658842 [ linux amd ] conformance2/buffers/uniform-buffers.html [ Failure ]
+crbug.com/658844 [ linux amd ] conformance2/rendering/uniform-block-buffer-size.html [ Failure ]
+crbug.com/2103 [ linux amd ] conformance2/uniforms/uniform-blocks-with-arrays.html [ Failure ]
+crbug.com/809595 [ no-angle linux amd ] conformance2/uniforms/simple-buffer-change.html [ Failure ]
+
+# Linux AMD R7 240
+crbug.com/710392 [ linux amd-0x6613 ] conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/710392 [ linux amd-0x6613 ] conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/710392 [ linux amd-0x6613 ] conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/710392 [ linux amd-0x6613 ] conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
+crbug.com/710392 [ linux amd-0x6613 ] conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
+crbug.com/710392 [ linux amd-0x6613 ] conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html [ Failure ]
+crbug.com/847217 [ linux amd-0x6613 ] conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html [ Failure ]
+crbug.com/847217 [ linux amd-0x6613 ] conformance2/textures/video/tex-2d-rg32f-rg-float.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html [ Failure ]
+crbug.com/701138 [ linux amd-0x6613 ] conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html [ Failure ]
+crbug.com/832864 [ no-angle linux amd-0x6613 ] conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html [ Failure ]
+crbug.com/696345 [ no-angle linux amd-0x6613 ] conformance2/transform_feedback/switching-objects.html [ Failure ]
+crbug.com/851159 [ linux amd-0x6613 ] conformance2/buffers/get-buffer-sub-data-validity.html [ Failure ]
+crbug.com/913301 [ linux amd-0x6613 ] conformance2/textures/misc/generate-mipmap-with-large-base-level.html [ Failure ]
+crbug.com/809237 [ linux amd-0x6613 ] conformance2/uniforms/incompatible-texture-type-for-sampler.html [ Skip ]
+
+####################
+# Android failures #
+####################
+
+# Skip these, rather than expect them to fail, to speed up test
+# execution. The browser is restarted even after expected test
+# failures.
+[ android ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
+[ android qualcomm ] WebglExtension_WEBGL_compressed_texture_s3tc [ Skip ]
+[ android qualcomm ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+
+# Basic failures that need to be investigated on multiple devices
+crbug.com/709351 [ android ] conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html [ Failure ]
+crbug.com/947236 [ android ] conformance2/uniforms/incompatible-texture-type-for-sampler.html [ Failure ]
+
+# Video tests are flaky. Sometimes the video is black.
+crbug.com/948894 [ android ] conformance/textures/video/* [ RetryOnFailure ]
+crbug.com/948894 [ android ] conformance/textures/image_bitmap_from_video/* [ RetryOnFailure ]
+crbug.com/948894 [ android ] conformance2/textures/video/* [ RetryOnFailure ]
+crbug.com/948894 [ android ] conformance2/textures/image_bitmap_from_video/* [ RetryOnFailure ]
+
+# 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/906739 [ android qualcomm ] conformance2/extensions/ovr_multiview2.html [ Failure ]
+crbug.com/906742 [ android qualcomm ] conformance2/glsl3/compare-structs-containing-arrays.html [ Failure ]
+crbug.com/906735 [ android qualcomm ] conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
+
+# This test is failing on Android Pixel 2 and 3 (Qualcomm)
+# Seems to be an OpenGL ES bug.
+crbug.com/945903 [ android qualcomm ] conformance2/rendering/vertex-id.html [ Failure ]
+crbug.com/906745 [ android qualcomm ] deqp/functional/gles3/shaderderivate_dfdy.html [ Failure ]
+crbug.com/695742 [ android qualcomm ] deqp/functional/gles3/multisample.html [ RetryOnFailure ]
+crbug.com/832238 [ android qualcomm ] conformance2/transform_feedback/switching-objects.html [ RetryOnFailure ]
+
+# This test is flaky but can fail three times in a row so it must be
+# marked as Fail instead of Flaky.
+crbug.com/946177 [ android qualcomm ] deqp/functional/gles3/shaderbuiltinvar.html [ Failure ]
+
+# Nvidia (Shield TV) failures
+crbug.com/906752 [ android nvidia ] conformance2/glsl3/array-complex-indexing.html [ Failure ]
+crbug.com/874620 [ android nvidia ] conformance2/glsl3/const-struct-from-array-as-function-parameter.html [ Failure ]
+crbug.com/905006 [ android nvidia ] conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html [ Failure ]
+
+# Conflicting expectations to test that the
+# "Expectations have no collisions" unittest works.
+
+# Conflict when all conditions match
+#[ linux nvidia-0x1 debug opengl ] test-page-1.html [ Failure ]
+#[ linux nvidia-0x1 debug opengl ] test-page-1.html [ Failure ]
+
+# Conflict when all conditions match (and different sets)
+#[ linux nvidia-0x1 debug opengl ] test-page-2.html [ Failure ]
+#[ linux nvidia-0x1 debug opengl amd ] test-page-2.html [ Failure ]
+#[ mac nvidia-0x1 debug opengl amd ] test-page-2.html [ Failure ]
+
+# Conflict with one aspect not specified
+#[ linux nvidia-0x1 debug ] test-page-3.html [ Failure ]
+#[ linux nvidia-0x1 debug opengl ] test-page-3.html [ Failure ]
+
+# Conflict with one aspect not specified (in both conditions)
+#[ linux nvidia-0x1 debug ] test-page-4.html [ Failure ]
+#[ linux nvidia-0x1 debug ] test-page-4.html [ Failure ]
+
+# Conflict even if the GPU is specified with a device ID
+#[ linux nvidia-0x1 debug ] WebglExtension_test_5 [ Failure ]
+#[ linux nvidia debug ] WebglExtension_test_5 [ Failure ]
+
+# Test there are no conflicts between two different devices
+#[ linux nvidia-0x1 debug ] WebglExtension_test_6 [ Failure ]
+#[ linux nvidia-0x2 debug ] WebglExtension_test_6 [ Failure ]
+
+# Test there are no conflicts between two devices with different vendors
+#[ linux nvidia-0x1 debug ] WebglExtension_test_7 [ Failure ]
+#[ linux amd-0x1 debug ] WebglExtension_test_7 [ Failure ]
+
+# Conflicts if there is a device and nothing specified for the other's GPU vendors
+#[ linux nvidia-0x1 debug ] WebglExtension_test_8 [ Failure ]
+#[ linux debug ] WebglExtension_test_8 [ Failure ]
+
+# Test no conflicts happen when only one aspect differs
+#[ linux nvidia-0x1 debug opengl ] WebglExtension_test_9 [ Failure ]
+#[ win nvidia-0x1 debug opengl ] WebglExtension_test_9 [ Failure ]
+
+# Conflicts if between a generic os condition and a specific version
+#[ sierra nvidia debug opengl ] WebglExtension_test_10 [ Failure ]
+#[ mac nvidia debug opengl ] WebglExtension_test_10 [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
new file mode 100644
index 0000000..0d465f2
--- /dev/null
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -0,0 +1,604 @@
+# tags: [ android chromeos linux mac win win10 win7 ]
+# tags: [ android-chromium android-webview-instrumentation debug release ]
+# tags: [ amd amd-0x6613 amd-0x699f intel intel-0xa011 intel-0xa2e nvidia
+#         nvidia-0x1cb3 nvidia-0xfe9 qualcomm qualcomm-adreno-(tm)-330
+#         qualcomm-adreno-(tm)-418 qualcomm-adreno-(tm)-420 qualcomm-adreno-(tm)-430 ]
+# tags: [ d3d11 d3d9 no-angle opengl opengles vulkan ]
+# tags: [ no-passthrough passthrough ]
+# tags: [ webgl-version-1 ]
+
+
+# ===================================
+# Extension availability expectations
+# ===================================
+# It's expected that not all extensions will be available on all platforms.
+# Having a test listed here is not necessarily a problem.
+[ win ] WebglExtension_EXT_color_buffer_float [ Failure ]
+[ mac ] WebglExtension_EXT_color_buffer_float [ Failure ]
+[ win vulkan passthrough ] WebglExtension_EXT_float_blend [ Failure ]
+crbug.com/2672 [ vulkan passthrough ] WebglExtension_WEBGL_multi_draw_instanced [ Failure ]
+
+# Skip these, rather than expect them to fail, to speed up test
+# execution. The browser is restarted even after expected test
+# failures.
+[ win ] WebglExtension_WEBGL_compressed_texture_astc [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_astc [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_astc [ Skip ]
+[ win ] WebglExtension_WEBGL_compressed_texture_etc1 [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_etc1 [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_etc1 [ Skip ]
+[ win ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
+[ win ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+[ mac ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+[ linux ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+[ android ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+crbug.com/808744 [ android ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
+crbug.com/849576 [ no-passthrough ] WebglExtension_KHR_parallel_shader_compile [ Skip ]
+
+# Extensions not available under D3D9
+[ win d3d9 ] WebglExtension_EXT_float_blend [ Failure ]
+[ win d3d9 ] WebglExtension_EXT_sRGB [ Failure ]
+crbug.com/867718 [ win d3d9 ] WebglExtension_EXT_disjoint_timer_query [ Failure ]
+[ win amd d3d9 ] WebglExtension_WEBGL_depth_texture [ Failure ]
+[ win d3d9 ] WebglExtension_WEBGL_draw_buffers [ Failure ]
+
+# Android general
+[ android ] WebglExtension_EXT_frag_depth [ Failure ]
+[ android ] WebglExtension_EXT_float_blend [ Failure ]
+[ android ] WebglExtension_EXT_shader_texture_lod [ Failure ]
+[ android ] WebglExtension_WEBGL_compressed_texture_astc [ Failure ]
+[ android ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Failure ]
+[ android ] WebglExtension_WEBGL_compressed_texture_s3tc [ Failure ]
+[ android ] WebglExtension_WEBGL_depth_texture [ Failure ]
+[ android ] WebglExtension_WEBGL_draw_buffers [ Failure ]
+
+# ========================
+# Conformance expectations
+# ========================
+# Fails on all platforms
+
+# TODO(shrekshao): Remove this after applying the new draw buffer
+# validation. And then uncomment the failure expectation for
+# angle bug 1523 (L160)
+crbug.com/927908 conformance/extensions/webgl-draw-buffers.html [ Failure ]
+
+# Need to implement new error semantics
+# https://github.com/KhronosGroup/WebGL/pull/2607
+crbug.com/849572 conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
+
+# Nvidia bugs fixed in latest driver
+# TODO(http://crbug.com/887241): Upgrade the drivers on the bots.
+crbug.com/772651 [ linux nvidia ] conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html [ Failure ]
+crbug.com/905370 [ android nvidia ] conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html [ Failure ]
+crbug.com/772651 [ nvidia ] conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html [ Failure ]
+crbug.com/798117 [ win nvidia vulkan ] conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html [ Failure ]
+crbug.com/798117 [ linux nvidia ] conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html [ Failure ]
+crbug.com/798117 [ android nvidia ] conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html [ Failure ]
+crbug.com/792210 [ nvidia ] conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html [ Failure ]
+
+# This test needs to be rewritten to measure its expected
+# performance; it's currently too flaky even on release bots.
+crbug.com/735483 conformance/rendering/texture-switch-performance.html [ Skip ]
+crbug.com/951628 [ passthrough ] conformance/rendering/blending.html [ Failure ]
+
+# TODO(shrekhao): Restore failure expectation for
+# ['win', 'nvidia', 'passthrough', 'd3d11'], bug=737016
+# as Flaky after 953120 is fixed.
+# And restore ['linux', 'intel'], bug=928530 as Fail
+crbug.com/953120 [ passthrough ] conformance/programs/program-test.html [ Failure ]
+
+# Passthrough command decoder / OpenGL
+crbug.com/2952 [ opengl passthrough ] conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html [ Failure ]
+crbug.com/2952 [ opengl passthrough ] conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
+
+# Intel graphics driver issue. Passed on 25.20.100.6471
+crbug.com/665521 [ intel opengl passthrough ] conformance/glsl/constructors/glsl-construct-mat2.html [ Failure ]
+
+# Passthrough command decoder / OpenGL / AMD
+# crbug.com/1523 [ amd opengl linux pass through ] conformance/extensions/webgl-draw-buffers.html [ Failure ]
+
+crbug.com/665521 [ amd opengl passthrough ] conformance/glsl/constructors/glsl-construct-mat2.html [ Failure ]
+crbug.com/665521 [ amd opengl passthrough ] conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html [ Failure ]
+crbug.com/665521 [ linux amd opengl passthrough ] conformance/glsl/constructors/glsl-construct-vec-mat-index.html [ Failure ]
+crbug.com/665521 [ linux amd opengl passthrough ] conformance/glsl/misc/shader-struct-scope.html [ Failure ]
+crbug.com/1007 [ linux amd opengl passthrough ] conformance/glsl/misc/shaders-with-invariance.html [ Skip ]
+crbug.com/665521 [ linux amd opengl passthrough ] conformance/glsl/misc/struct-nesting-of-variable-names.html [ Failure ]
+crbug.com/1635 [ amd opengl passthrough ] conformance/renderbuffers/renderbuffer-initialization.html [ Failure ]
+crbug.com/665521 [ amd opengl passthrough ] conformance/renderbuffers/framebuffer-state-restoration.html [ Failure ]
+crbug.com/665521 [ amd opengl passthrough ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Failure ]
+crbug.com/665521 [ amd opengl passthrough ] conformance/textures/misc/texture-attachment-formats.html [ Failure ]
+
+# Win / AMD / Passthrough command decoder / D3D11
+crbug.com/685232 [ win amd d3d11 passthrough ] conformance/textures/misc/copytexsubimage2d-subrects.html [ RetryOnFailure ]
+crbug.com/772037 [ win7 debug amd d3d11 passthrough ] conformance/textures/misc/texture-sub-image-cube-maps.html [ RetryOnFailure ]
+crbug.com/772037 [ win7 release amd d3d11 passthrough ] conformance/extensions/oes-texture-half-float.html [ RetryOnFailure ]
+
+# Win / NVIDIA / Passthrough command decoder / D3D11
+crbug.com/751849 [ win7 debug nvidia d3d11 passthrough ] conformance/extensions/oes-texture-half-float-with-video.html [ RetryOnFailure ]
+# crbug.com/737016 [ win nvidia d3d11 passthrough ] conformance/programs/program-test.html [ RetryOnFailure ]
+
+# Win failures
+# TODO(kbr): re-enable suppression for same test below once fixed.
+crbug.com/2103 [ win ] conformance/glsl/bugs/sampler-struct-function-arg.html [ Skip ]
+
+# Note that the following test seems to pass, but it may still be flaky.
+crbug.com/525188 [ win ] conformance/glsl/constructors/glsl-construct-vec-mat-index.html [ RetryOnFailure ]
+crbug.com/478572 [ win ] deqp/data/gles2/shaders/functions.html [ Failure ]
+crbug.com/931006 [ win ] conformance/textures/misc/texture-active-bind.html [ Failure ]
+crbug.com/951628 [ win no-passthrough ] conformance/rendering/blending.html [ Failure ]
+
+# Win NVIDIA failures
+crbug.com/626524 [ win nvidia no-passthrough ] conformance/textures/misc/texture-npot-video.html [ RetryOnFailure ]
+crbug.com/630860 [ win nvidia ] conformance/textures/misc/texture-upload-size.html [ RetryOnFailure ]
+crbug.com/3018 [ win nvidia vulkan passthrough ] conformance/rendering/out-of-bounds-index-buffers.html [ Skip ]
+
+# crbug.com/679696 [ win nvidia no_passthrough ] conformance/extensions/ext-sRGB.html [ Failure ]
+
+# Win10 / NVIDIA Quadro P400 / D3D9 failures
+crbug.com/829389 [ win10 nvidia-0x1cb3 d3d9 ] conformance/canvas/canvas-test.html [ RetryOnFailure ]
+crbug.com/680754 [ win10 nvidia-0x1cb3 d3d9 ] conformance/canvas/drawingbuffer-static-canvas-test.html [ Failure ]
+crbug.com/680754 [ win10 nvidia-0x1cb3 d3d9 ] conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html [ Failure ]
+crbug.com/750896 [ win10 nvidia-0x1cb3 d3d9 ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
+crbug.com/829389 [ win10 nvidia-0x1cb3 d3d9 ] conformance/glsl/misc/shader-with-non-reserved-words.html [ RetryOnFailure ]
+crbug.com/825416 [ win10 nvidia-0x1cb3 d3d9 ] conformance/glsl/variables/gl-frontfacing.html [ RetryOnFailure ]
+crbug.com/737018 [ win10 nvidia-0x1cb3 d3d9 ] conformance/ogles/GL/atan/atan_001_to_008.html [ Failure ]
+crbug.com/680754 [ win10 nvidia-0x1cb3 d3d9 ] conformance/ogles/GL/cos/cos_001_to_006.html [ Failure ]
+crbug.com/750896 [ win10 nvidia-0x1cb3 d3d9 ] conformance/textures/image_bitmap_from_video/* [ RetryOnFailure ]
+crbug.com/750896 [ win10 nvidia-0x1cb3 d3d9 ] conformance/textures/video/* [ RetryOnFailure ]
+crbug.com/750896 [ win10 nvidia-0x1cb3 d3d9 ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
+crbug.com/829389 [ win10 nvidia-0x1cb3 d3d9 passthrough ] conformance/uniforms/uniform-samplers-test.html [ RetryOnFailure ]
+
+# Win10 / NVIDIA Quadro P400 failures
+crbug.com/728670 [ win10 nvidia-0x1cb3 ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
+crbug.com/728670 [ win10 nvidia-0x1cb3 ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ]
+
+# Win7 / NVIDIA D3D9 failures
+crbug.com/690248 [ win7 nvidia d3d9 ] conformance/canvas/canvas-test.html [ RetryOnFailure ]
+
+# Win / Intel
+crbug.com/825338 [ win intel ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
+crbug.com/929009 [ win intel ] conformance/glsl/misc/shader-with-non-reserved-words.html [ RetryOnFailure ]
+
+# This is an OpenGL driver bug on Intel platform and it is fixed in
+# Intel Driver 25.20.100.6444.
+# Case no-over-optimization-on-uniform-array-09 always fail if run
+# case biuDepthRange_001_to_002 first.
+# Temporarily skip these two cases now because this issue blocks
+# WEBGL_video_texture implementation.
+crbug.com/907195 [ win intel opengl passthrough ] conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html [ Skip ]
+crbug.com/907195 [ win intel opengl passthrough ] conformance/uniforms/no-over-optimization-on-uniform-array-09.html [ Skip ]
+
+# Win7 / Intel failures
+[ win7 intel no-passthrough ] conformance/textures/misc/copy-tex-image-and-sub-image-2d.html [ Failure ]
+
+# Win AMD failures
+# This test is probably flaky on all AMD, but only visible on the
+# new AMD (the whole test suite is flaky on the old config).
+# Mark as Fail since it often flakes in all 3 retries
+crbug.com/653533 [ win amd-0x6613 no-passthrough ] conformance/extensions/oes-texture-half-float.html [ Failure ]
+
+# Win / AMD D3D11 failures
+crbug.com/878780 [ win amd ] conformance/textures/webgl_canvas/* [ RetryOnFailure ]
+
+# Win / AMD D3D9 failures
+crbug.com/475095 [ win amd d3d9 ] conformance/extensions/angle-instanced-arrays.html [ Failure ]
+crbug.com/475095 [ win amd d3d9 ] conformance/rendering/more-than-65536-indices.html [ Failure ]
+
+# Win / D3D9 failures
+# Skipping these two tests because they're causing assertion failures.
+crbug.com/896 [ win d3d9 no-passthrough ] conformance/extensions/oes-texture-float-with-canvas.html [ Skip ]
+crbug.com/896 [ win d3d9 no-passthrough ] conformance/extensions/oes-texture-half-float-with-canvas.html [ Skip ]
+crbug.com/1179 [ win d3d9 ] conformance/glsl/bugs/floor-div-cos-should-not-truncate.html [ Failure ]
+
+# The functions test have been persistently flaky on D3D9
+crbug.com/415609 [ win d3d9 ] conformance/glsl/functions/* [ RetryOnFailure ]
+crbug.com/617148 [ win d3d9 ] conformance/glsl/matrices/glsl-mat4-to-mat3.html [ RetryOnFailure ]
+crbug.com/617148 [ win d3d9 ] conformance/glsl/matrices/glsl-mat3-construction.html [ RetryOnFailure ]
+crbug.com/674572 [ win d3d9 ] conformance/glsl/misc/large-loop-compile.html [ Skip ]
+crbug.com/956134 [ win d3d9 ] conformance/extensions/webgl-depth-texture.html [ Skip ]
+
+# WIN / OpenGL / NVIDIA failures
+crbug.com/715001 [ win nvidia-0x1cb3 opengl passthrough ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
+crbug.com/703779 [ win nvidia-0x1cb3 opengl ] conformance/textures/misc/texture-size.html [ Failure ]
+
+# Mark ANGLE's OpenGL as flaky on Windows Nvidia
+crbug.com/582083 [ win nvidia opengl ] conformance/* [ RetryOnFailure ]
+
+# Win / OpenGL / AMD failures
+crbug.com/649824 [ win amd opengl ] conformance/attribs/gl-bindAttribLocation-aliasing.html [ Skip ]
+crbug.com/1007 [ win amd opengl ] conformance/glsl/misc/shader-struct-scope.html [ Skip ]
+crbug.com/1007 [ win amd opengl no-passthrough ] conformance/glsl/misc/shaders-with-invariance.html [ Skip ]
+crbug.com/1007 [ win amd opengl ] conformance/glsl/misc/struct-nesting-of-variable-names.html [ Failure ]
+crbug.com/1506 [ win amd opengl ] conformance/rendering/clipping-wide-points.html [ Failure ]
+
+# AMD RX 550 Failures
+crbug.com/950123 [ win amd-0x699f opengl ] conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html [ Skip ]
+crbug.com/950123 [ win amd-0x699f opengl ] conformance/glsl/misc/fragcolor-fragdata-invariant.html [ Skip ]
+crbug.com/950123 [ win amd-0x699f opengl ] conformance/glsl/samplers/glsl-function-texture2dprojlod.html [ Skip ]
+crbug.com/951771 [ win amd-0x699f opengl ] conformance/reading/read-pixels-test.html [ Failure ]
+crbug.com/950123 [ win amd-0x699f opengl ] conformance/rendering/line-rendering-quality.html [ Skip ]
+crbug.com/952887 [ win amd-0x699f opengl passthrough ] conformance/rendering/multisample-corruption.html [ Skip ]
+
+# Mark ANGLE's OpenGL as flaky on Windows Amd
+crbug.com/582083 [ win amd opengl ] conformance/* [ RetryOnFailure ]
+
+# Win / OpenGL / Intel HD 530 / 630 failures
+crbug.com/854100 [ win10 intel opengl ] conformance/glsl/variables/gl-pointcoord.html [ RetryOnFailure ]
+
+# Win / Intel / Passthrough command decoder
+crbug.com/602688 [ win intel d3d11 passthrough ] conformance/renderbuffers/framebuffer-state-restoration.html [ RetryOnFailure ]
+
+# D3D9 / Passthrough command decoder
+crbug.com/2192 [ win d3d9 passthrough ] conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
+crbug.com/2192 [ win d3d9 passthrough ] conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
+crbug.com/2192 [ win d3d9 passthrough ] conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
+crbug.com/2192 [ win d3d9 passthrough ] conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
+crbug.com/2192 [ win d3d9 passthrough ] conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
+crbug.com/2192 [ win d3d9 passthrough ] conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
+crbug.com/2192 [ win d3d9 passthrough ] conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
+crbug.com/2192 [ win d3d9 passthrough ] conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
+
+# Vulkan / Win / Passthough command decoder
+crbug.com/2708 [ win vulkan passthrough ] conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html [ Failure ]
+crbug.com/2929 [ win vulkan passthrough ] conformance/canvas/canvas-test.html [ Failure ]
+crbug.com/2918 [ win vulkan passthrough ] conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html [ Failure ]
+crbug.com/2918 [ win vulkan passthrough ] conformance/canvas/draw-webgl-to-canvas-test.html [ Failure ]
+crbug.com/2913 [ win vulkan passthrough ] conformance/context/context-attribute-preserve-drawing-buffer.html [ Failure ]
+crbug.com/2987 [ win vulkan passthrough ] conformance/misc/uninitialized-test.html [ Failure ]
+crbug.com/2911 [ win vulkan passthrough ] conformance/more/functions/copyTexSubImage2D.html [ Failure ]
+crbug.com/2916 [ win vulkan passthrough ] conformance/offscreencanvas/context-lost-restored-worker.html [ Failure ]
+crbug.com/2916 [ win vulkan passthrough ] conformance/offscreencanvas/context-lost-restored.html [ Failure ]
+crbug.com/2909 [ win vulkan passthrough ] conformance/ogles/GL/faceforward/faceforward_001_to_006.html [ Failure ]
+crbug.com/2722 [ win vulkan passthrough ] conformance/renderbuffers/depth-renderbuffer-initialization.html [ Failure ]
+crbug.com/2910 [ win vulkan passthrough ] conformance/renderbuffers/framebuffer-object-attachment.html [ Failure ]
+crbug.com/2722 [ win vulkan passthrough ] conformance/renderbuffers/framebuffer-state-restoration.html [ Failure ]
+[ win vulkan passthrough ] conformance/renderbuffers/stencil-renderbuffer-initialization.html [ Failure ]
+crbug.com/2919 [ win vulkan passthrough ] conformance/rendering/preservedrawingbuffer-leak.html [ Failure ]
+crbug.com/2722 [ win vulkan passthrough ] conformance/textures/misc/copy-tex-image-and-sub-image-2d.html [ Failure ]
+crbug.com/2722 [ win vulkan passthrough ] conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html [ Failure ]
+crbug.com/2722 [ win vulkan passthrough ] conformance/textures/misc/copytexsubimage2d-subrects.html [ Failure ]
+crbug.com/2920 [ win vulkan passthrough ] conformance/textures/misc/gl-pixelstorei.html [ Failure ]
+crbug.com/2912 [ win vulkan passthrough ] conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html [ Failure ]
+crbug.com/2722 [ win vulkan passthrough ] conformance/textures/misc/tex-image-webgl.html [ Failure ]
+crbug.com/2722 [ win vulkan passthrough ] conformance/textures/misc/texture-attachment-formats.html [ Failure ]
+crbug.com/2914 [ win vulkan passthrough ] conformance/textures/misc/texture-copying-feedback-loops.html [ Failure ]
+crbug.com/2913 [ win vulkan passthrough ] conformance/textures/misc/texture-hd-dpi.html [ Failure ]
+crbug.com/2722 [ win vulkan passthrough ] conformance/textures/misc/texture-mips.html [ Failure ]
+
+# Note: the following test crashes so it's skipped.  http://anglebug.com/3352
+crbug.com/2921 [ win vulkan passthrough ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Skip ]
+crbug.com/2672 [ win vulkan passthrough ] WebglExtension_ANGLE_instanced_arrays [ Failure ]
+crbug.com/2897 [ win vulkan passthrough ] WebglExtension_EXT_blend_minmax [ Failure ]
+crbug.com/2898 [ win vulkan passthrough ] WebglExtension_EXT_color_buffer_half_float [ Failure ]
+crbug.com/2885 [ win vulkan passthrough ] WebglExtension_EXT_disjoint_timer_query [ Failure ]
+crbug.com/2887 [ win vulkan passthrough ] WebglExtension_EXT_frag_depth [ Failure ]
+crbug.com/2899 [ win vulkan passthrough ] WebglExtension_EXT_shader_texture_lod [ Failure ]
+crbug.com/2902 [ win vulkan passthrough ] WebglExtension_OES_element_index_uint [ Failure ]
+crbug.com/2903 [ win vulkan passthrough ] WebglExtension_OES_standard_derivatives [ Failure ]
+crbug.com/2898 [ win vulkan passthrough ] WebglExtension_OES_texture_float [ Failure ]
+crbug.com/2898 [ win vulkan passthrough ] WebglExtension_OES_texture_float_linear [ Failure ]
+crbug.com/2898 [ win vulkan passthrough ] WebglExtension_OES_texture_half_float [ Failure ]
+crbug.com/2898 [ win vulkan passthrough ] WebglExtension_OES_texture_half_float_linear [ Failure ]
+crbug.com/2898 [ win vulkan passthrough ] WebglExtension_WEBGL_color_buffer_float [ Failure ]
+crbug.com/2904 [ win vulkan passthrough ] WebglExtension_WEBGL_compressed_texture_s3tc [ Failure ]
+crbug.com/2905 [ win vulkan passthrough ] WebglExtension_WEBGL_depth_texture [ Failure ]
+crbug.com/2394 [ win vulkan passthrough ] WebglExtension_WEBGL_draw_buffers [ Failure ]
+crbug.com/3111 [ win vulkan passthrough ] deqp/data/gles2/shaders/swizzles.html [ Skip ]
+
+# Vulkan / Win / NVIDIA / Passthough command decoder
+crbug.com/2918 [ win nvidia vulkan passthrough ] conformance/canvas/to-data-url-test.html [ Failure ]
+crbug.com/2922 [ win nvidia vulkan passthrough ] conformance/context/premultiplyalpha-test.html [ Failure ]
+crbug.com/2939 [ win nvidia vulkan passthrough ] conformance/rendering/gl-scissor-fbo-test.html [ RetryOnFailure ]
+crbug.com/2915 [ win nvidia vulkan passthrough ] conformance/textures/misc/texture-size.html [ Failure ]
+crbug.com/2930 [ win nvidia vulkan passthrough ] conformance/textures/misc/texture-size-cube-maps.html [ Failure ]
+crbug.com/2915 [ win nvidia vulkan passthrough ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
+crbug.com/2926 [ win nvidia vulkan passthrough ] deqp/data/gles2/shaders/conversions.html [ Failure ]
+
+# Vulkan / Win / Intel / Passthough command decoder
+crbug.com/2722 [ win intel vulkan passthrough ] conformance/rendering/clipping-wide-points.html [ Failure ]
+
+# Vulkan / Win / AMD / Passthough command decoder
+crbug.com/2931 [ win amd vulkan passthrough ] conformance/buffers/buffer-data-dynamic-delay.html [ Failure ]
+crbug.com/2918 [ win amd vulkan passthrough ] conformance/canvas/to-data-url-test.html [ Failure ]
+crbug.com/2922 [ win amd vulkan passthrough ] conformance/context/premultiplyalpha-test.html [ Failure ]
+crbug.com/2722 [ win amd vulkan passthrough ] conformance/rendering/clipping-wide-points.html [ Failure ]
+crbug.com/2926 [ win amd vulkan passthrough ] deqp/data/gles2/shaders/conversions.html [ Failure ]
+crbug.com/2926 [ win amd vulkan passthrough ] deqp/data/gles2/shaders/linkage.html [ Failure ]
+crbug.com/931016 [ win amd vulkan passthrough ] conformance/textures/image_bitmap_from_canvas/tex-2d-luminance* [ Failure ]
+crbug.com/931016 [ win amd vulkan passthrough ] conformance/textures/image_bitmap_from_canvas/tex-2d-rgb* [ Failure ]
+crbug.com/3343 [ win amd vulkan passthrough ] conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html [ Failure ]
+crbug.com/857644 [ win passthrough amd vulkan ] conformance/glsl/samplers/glsl-function-texture2dproj.html [ Failure ]
+crbug.com/957644 [ win passthrough amd vulkan ] conformance/glsl/samplers/glsl-function-texture2dprojlod.html [ Failure ]
+crbug.com/957644 [ win passthrough amd vulkan ] conformance/textures/misc/texture-corner-case-videos.html [ Failure ]
+
+# Mac failures
+crbug.com/844311 [ mac ] conformance/glsl/misc/fragcolor-fragdata-invariant.html [ Failure ]
+crbug.com/599272 [ mac no-passthrough ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
+crbug.com/928926 [ mac ] conformance/ogles/GL/abs/abs_001_to_006.html [ RetryOnFailure ]
+
+# Mac AMD failures
+crbug.com/905007 [ mac amd ] conformance/glsl/bugs/bool-type-cast-bug-int-float.html [ Failure ]
+crbug.com/642822 [ mac amd ] conformance/rendering/clipping-wide-points.html [ Failure ]
+crbug.com/929009 [ mac amd ] conformance/glsl/misc/shader-with-non-reserved-words.html [ RetryOnFailure ]
+
+# TODO(kbr): uncomment the following exepectation after test has
+# been made more robust.
+# crbug.com/735483 [ mac amd release ] conformance/rendering/texture-switch-performance.html [ Failure ]
+
+# Mac Intel
+crbug.com/886970 [ mac intel-0xa2e ] conformance/rendering/canvas-alpha-bug.html [ Failure ]
+crbug.com/782317 [ mac intel ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
+
+# Mac Retina NVidia failures
+crbug.com/635081 [ mac nvidia-0xfe9 ] conformance/attribs/gl-disabled-vertex-attrib.html [ Failure ]
+crbug.com/923080 [ mac nvidia-0xfe9 ] conformance/ogles/GL/exp2/exp2_001_to_008.html [ RetryOnFailure ]
+crbug.com/635081 [ mac nvidia-0xfe9 ] conformance/programs/gl-bind-attrib-location-long-names-test.html [ Failure ]
+crbug.com/635081 [ mac nvidia-0xfe9 ] conformance/programs/gl-bind-attrib-location-test.html [ Failure ]
+crbug.com/635081 [ mac nvidia-0xfe9 no-passthrough ] conformance/renderbuffers/framebuffer-object-attachment.html [ Failure ]
+crbug.com/635081 [ mac nvidia-0xfe9 ] conformance/textures/misc/tex-input-validation.html [ Failure ]
+crbug.com/784817 [ mac nvidia-0xfe9 ] conformance/glsl/bugs/init-array-with-loop.html [ Failure ]
+crbug.com/871352 [ mac debug nvidia-0xfe9 ] conformance/uniforms/uniform-samplers-test.html [ Failure ]
+crbug.com/948218 [ mac debug nvidia-0xfe9 ] conformance/glsl/misc/shader-with-non-reserved-words.html [ Failure ]
+
+# Already fixed with Mesa 17.1.6
+crbug.com/680675 [ linux intel ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ]
+
+# NVIDIA
+crbug.com/524144 [ linux nvidia no-passthrough ] conformance/extensions/oes-element-index-uint.html [ RetryOnFailure ]
+crbug.com/596622 [ linux nvidia ] conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ]
+
+# NVIDIA P400 OpenGL
+crbug.com/715001 [ linux nvidia-0x1cb3 ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
+crbug.com/703779 [ linux nvidia-0x1cb3 opengl ] conformance/textures/misc/texture-size.html [ Failure ]
+crbug.com/913969 [ linux nvidia-0x1cb3 ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
+crbug.com/913969 [ linux nvidia-0x1cb3 ] conformance/extensions/oes-texture-half-float-with-video.html [ RetryOnFailure ]
+
+# NVIDIA P400 OpenGL, Debug
+crbug.com/918995 [ linux debug nvidia-0x1cb3 ] conformance/canvas/draw-webgl-to-canvas-test.html [ RetryOnFailure ]
+crbug.com/918995 [ linux debug nvidia-0x1cb3 ] conformance/extensions/webgl-depth-texture.html [ RetryOnFailure ]
+crbug.com/918995 [ linux debug nvidia-0x1cb3 ] conformance/rendering/polygon-offset.html [ RetryOnFailure ]
+
+# AMD
+crbug.com/844311 [ linux amd ] conformance/glsl/misc/fragcolor-fragdata-invariant.html [ Failure ]
+crbug.com/550989 [ linux amd ] conformance/more/functions/uniformi.html [ RetryOnFailure ]
+crbug.com/642822 [ linux amd ] conformance/rendering/clipping-wide-points.html [ Failure ]
+
+# AMD Radeon 6450 and/or R7 240
+crbug.com/479260 [ linux amd no-angle ] conformance/extensions/angle-instanced-arrays.html [ Failure ]
+crbug.com/479952 [ linux amd no-passthrough ] conformance/glsl/misc/shaders-with-invariance.html [ Failure ]
+
+# Linux passthrough AMD
+crbug.com/794339 [ linux amd passthrough ] conformance/renderbuffers/depth-renderbuffer-initialization.html [ Failure ]
+crbug.com/794339 [ linux amd passthrough ] conformance/renderbuffers/stencil-renderbuffer-initialization.html [ Failure ]
+crbug.com/906066 [ linux amd passthrough ] conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html [ Failure ]
+
+# The following two tests only fail on Linux/Intel with Mesa 18.0.5,
+# not on Mesa 17.1.4 with the same Intel HD 630 GPU.
+crbug.com/928530 [ linux intel no-passthrough ] conformance/programs/program-test.html [ Failure ]
+
+
+####################
+# Android failures #
+####################
+
+crbug.com/903903 [ android ] conformance/glsl/bugs/sampler-array-struct-function-arg.html [ Failure ]
+crbug.com/478572 [ android qualcomm ] conformance/glsl/bugs/sequence-operator-evaluation-order.html [ Failure ]
+
+# The following test is very slow and therefore times out on Android bot.
+[ android ] conformance/rendering/multisample-corruption.html [ Skip ]
+crbug.com/679697 [ android qualcomm no-passthrough ] conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html [ Failure ]
+crbug.com/951628 [ android no-passthrough ] conformance/rendering/blending.html [ Failure ]
+
+# The following WebView crashes are causing problems with further
+# tests in the suite, so skip them for now.
+crbug.com/352645 [ android android-webview-instrumentation ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html [ Skip ]
+
+# Also flaky on nexus9 non-webview (bug=834933) but can't specify both.
+crbug.com/352645 [ android ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ Skip ]
+crbug.com/352645 [ android android-webview-instrumentation ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html [ Skip ]
+crbug.com/352645 [ android android-webview-instrumentation ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Skip ]
+crbug.com/352645 [ android-webview-instrumentation ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Skip ]
+crbug.com/352645 [ android android-webview-instrumentation no-angle ] conformance/textures/misc/texture-npot-video.html [ Skip ]
+
+# These video tests appear to be flaky.
+crbug.com/907512 [ android release no-angle ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
+crbug.com/733599 [ android no-angle ] conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/733599 [ android no-angle ] conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/733599 [ android no-angle ] conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/834933 [ android android-chromium no-angle ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/834933 [ android android-chromium no-angle ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html [ RetryOnFailure ]
+
+# This crashes in Android WebView on the Nexus 6, preventing the
+# suite from running further. Rather than add multiple
+# suppressions, skip it until it's passing at least in content
+# shell.
+crbug.com/499555 [ android qualcomm ] conformance/extensions/oes-texture-float-with-video.html [ Skip ]
+
+# Nexus 5
+crbug.com/899754 [ android qualcomm-adreno-(tm)-330 ] conformance/attribs/gl-disabled-vertex-attrib-update.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/extensions/angle-instanced-arrays.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/extensions/ext-texture-filter-anisotropic.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/bugs/array-of-struct-with-int-first-position.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html [ Failure ]
+crbug.com/527761 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/bugs/sampler-struct-function-arg.html [ Failure ]
+crbug.com/559342 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/bugs/struct-constructor-highp-bug.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/matrices/glsl-mat4-to-mat3.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/misc/shader-struct-scope.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 no-passthrough ] conformance/glsl/misc/shaders-with-invariance.html [ Failure ]
+crbug.com/611943 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/misc/struct-equals.html [ Failure ]
+crbug.com/478572 [ android qualcomm-adreno-(tm)-330 ] deqp/data/gles2/shaders/linkage.html [ Failure ]
+[ android qualcomm-adreno-(tm)-330 no-passthrough ] WebglExtension_OES_texture_float_linear [ Failure ]
+crbug.com/678850 [ android qualcomm-adreno-(tm)-330 ] conformance/more/functions/vertexAttribPointerBadArgs.html [ Failure ]
+crbug.com/678850 [ android qualcomm-adreno-(tm)-330 ] conformance/attribs/gl-vertexattribpointer.html [ Failure ]
+crbug.com/709704 [ android qualcomm-adreno-(tm)-330 ] conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html [ Failure ]
+
+# Nexus 5X
+# The following test recently became so flaky that it had to be
+# upgraded to Fail.
+crbug.com/882323 [ android qualcomm-adreno-(tm)-418 ] deqp/data/gles2/shaders/conversions.html [ Failure ]
+
+# The following test just started timing out randomly on the
+# android_optional_gpu_tests_rel tryserver with no apparent cause.
+crbug.com/793050 [ android qualcomm-adreno-(tm)-418 ] deqp/data/gles2/shaders/swizzles.html [ RetryOnFailure ]
+
+# This one is causing intermittent timeouts on the device, and it
+# looks like when that happens, the next test also always times
+# out. Skip it for now until it's fixed and running reliably.
+crbug.com/609883 [ android qualcomm-adreno-(tm)-418 ] conformance/extensions/oes-texture-half-float-with-video.html [ Skip ]
+
+# This test is skipped because it is crashing the GPU process.
+crbug.com/784817 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/bugs/init-array-with-loop.html [ Skip ]
+crbug.com/920737 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/bugs/loop-if-loop-gradient.html [ RetryOnFailure ]
+crbug.com/609883 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/bugs/sampler-struct-function-arg.html [ Failure ]
+crbug.com/912161 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/constructors/glsl-construct-ivec4.html [ RetryOnFailure ]
+crbug.com/912161 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/constructors/glsl-construct-mat2.html [ RetryOnFailure ]
+crbug.com/912161 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html [ RetryOnFailure ]
+crbug.com/912161 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/functions/glsl-function-dot.html [ RetryOnFailure ]
+crbug.com/912161 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/functions/glsl-function-min-gentype.html [ RetryOnFailure ]
+crbug.com/912161 [ android qualcomm-adreno-(tm)-418 ] conformance/glsl/implicit/add_ivec3_vec3.vert.html [ RetryOnFailure ]
+
+# This test is skipped because it is crashing the GPU process.
+crbug.com/609883 [ android qualcomm-adreno-(tm)-418 no-passthrough ] conformance/glsl/misc/shader-with-non-reserved-words.html [ Skip ]
+crbug.com/793050 [ android qualcomm-adreno-(tm)-418 ] conformance/ogles/GL/all/all_001_to_004.html [ RetryOnFailure ]
+crbug.com/793050 [ android qualcomm-adreno-(tm)-418 ] conformance/ogles/GL/cos/cos_001_to_006.html [ RetryOnFailure ]
+crbug.com/818041 [ android qualcomm-adreno-(tm)-418 ] conformance/ogles/GL/dot/dot_001_to_006.html [ RetryOnFailure ]
+crbug.com/793050 [ android qualcomm-adreno-(tm)-418 ] conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html [ RetryOnFailure ]
+crbug.com/818041 [ android qualcomm-adreno-(tm)-418 no-angle ] conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/793050 [ android qualcomm-adreno-(tm)-418 no-angle ] conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/716496 [ android qualcomm-adreno-(tm)-418 no-angle ] conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/934545 [ android android-chromium qualcomm-adreno-(tm)-418 no-angle ] conformance/textures/misc/texture-npot-video.html [ RetryOnFailure ]
+crbug.com/610951 [ android qualcomm-adreno-(tm)-418 ] conformance/uniforms/uniform-samplers-test.html [ Skip ]
+crbug.com/610951 [ android qualcomm-adreno-(tm)-418 ] WebglExtension_EXT_sRGB [ Failure ]
+crbug.com/914631 [ android qualcomm-adreno-(tm)-418 passthrough ] conformance/limits/gl-max-texture-dimensions.html [ RetryOnFailure ]
+
+# Nexus 6 (Adreno 420) and 6P (Adreno 430)
+crbug.com/499555 [ android qualcomm-adreno-(tm)-420 ] conformance/context/context-attributes-alpha-depth-stencil-antialias.html [ Failure ]
+crbug.com/611945 [ android qualcomm-adreno-(tm)-420 no-angle ] conformance/context/context-size-change.html [ Failure ]
+crbug.com/499555 [ android qualcomm-adreno-(tm)-420 ] conformance/context/premultiplyalpha-test.html [ Failure ]
+crbug.com/611945 [ android qualcomm-adreno-(tm)-420 ] conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html [ Failure ]
+crbug.com/611945 [ android qualcomm-adreno-(tm)-420 ] conformance/glsl/bugs/qualcomm-crash.html [ Failure ]
+crbug.com/611945 [ qualcomm-adreno-(tm)-420 android ] conformance/glsl/bugs/sampler-struct-function-arg.html [ Failure ]
+crbug.com/611945 [ qualcomm-adreno-(tm)-430 android ] conformance/glsl/bugs/sampler-struct-function-arg.html [ Failure ]
+
+# This test is skipped because running it causes a future test to fail.
+# The list of tests which may be that future test is very long. It is
+# almost (but not quite) every webgl conformance test.
+crbug.com/614550 [ android qualcomm-adreno-(tm)-420 ] conformance/glsl/misc/shader-struct-scope.html [ Skip ]
+crbug.com/611945 [ android qualcomm-adreno-(tm)-420 no-passthrough ] conformance/glsl/misc/shaders-with-invariance.html [ Failure ]
+
+# bindBufferBadArgs is causing the GPU thread to crash, taking
+# down the WebView shell, causing the next test to fail and
+# subsequent tests to be aborted.
+crbug.com/499874 [ android android-webview-instrumentation qualcomm-adreno-(tm)-420 ] conformance/more/functions/bindBufferBadArgs.html [ Skip ]
+crbug.com/899754 [ android qualcomm-adreno-(tm)-420 ] conformance/reading/fbo-remains-unchanged-after-read-pixels.html [ Failure ]
+crbug.com/899754 [ android qualcomm-adreno-(tm)-420 ] conformance/reading/read-pixels-pack-alignment.html [ Failure ]
+crbug.com/899754 [ android qualcomm-adreno-(tm)-420 ] conformance/reading/read-pixels-test.html [ Failure ]
+crbug.com/737002 [ android qualcomm-adreno-(tm)-420 ] conformance/rendering/clear-after-copyTexImage2D.html [ Failure ]
+crbug.com/911918 [ android qualcomm-adreno-(tm)-420 ] conformance/rendering/color-mask-preserved-during-implicit-clears.html [ Failure ]
+crbug.com/499555 [ android qualcomm-adreno-(tm)-420 ] conformance/rendering/gl-scissor-test.html [ Failure ]
+crbug.com/611945 [ android qualcomm-adreno-(tm)-420 ] conformance/rendering/gl-viewport-test.html [ Failure ]
+crbug.com/847222 [ android qualcomm-adreno-(tm)-420 ] conformance/rendering/line-rendering-quality.html [ Failure ]
+crbug.com/499555 [ android qualcomm-adreno-(tm)-420 no-passthrough ] conformance/textures/misc/copy-tex-image-and-sub-image-2d.html [ Failure ]
+crbug.com/663071 [ android qualcomm-adreno-(tm)-430 ] conformance/uniforms/uniform-samplers-test.html [ Skip ]
+crbug.com/693135 [ android qualcomm-adreno-(tm)-420 ] conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html [ Failure ]
+[ qualcomm-adreno-(tm)-420 android ] WebglExtension_EXT_sRGB [ Failure ]
+[ qualcomm-adreno-(tm)-430 android ] WebglExtension_EXT_sRGB [ Failure ]
+crbug.com/2046 [ android qualcomm-adreno-(tm)-420 ] conformance/glsl/misc/uninitialized-local-global-variables.html [ Failure ]
+
+# Nexus 9
+crbug.com/478572 [ android nvidia ] deqp/data/gles2/shaders/functions.html [ Failure ]
+crbug.com/606096 [ android nvidia ] conformance/glsl/bugs/multiplication-assignment.html [ Failure ]
+crbug.com/912161 [ android nvidia ] conformance/glsl/constructors/glsl-construct-ivec4.html [ RetryOnFailure ]
+crbug.com/912161 [ android nvidia ] conformance/glsl/constructors/glsl-construct-mat2.html [ RetryOnFailure ]
+crbug.com/891456 [ android nvidia ] conformance/extensions/oes-texture-half-float-with-video.html [ RetryOnFailure ]
+crbug.com/891456 [ android nvidia ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
+crbug.com/891456 [ android nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ]
+
+# Flaky timeout on android_n5x_swarming_rel and
+# android-marshmallow-arm64-rel.
+crbug.com/845411 [ android ] conformance/glsl/constructors/glsl-construct-mat3.html [ RetryOnFailure ]
+crbug.com/845438 [ android ] conformance/glsl/bugs/sketchfab-lighting-shader-crash.html [ RetryOnFailure ]
+
+# Android ANGLE GLES
+# Video tests time out
+crbug.com/906724 [ android opengles ] conformance/textures/image_bitmap_from_video/* [ Skip ]
+crbug.com/906724 [ android opengles ] conformance/textures/misc/tex-video-using-tex-unit-non-zero.html [ Skip ]
+crbug.com/906724 [ android opengles ] conformance/textures/misc/texture-corner-case-videos.html [ Skip ]
+crbug.com/906724 [ android opengles ] conformance/textures/misc/texture-npot-video.html [ Skip ]
+crbug.com/906724 [ android opengles ] conformance/textures/misc/texture-upload-size.html [ Skip ]
+crbug.com/906724 [ android opengles ] conformance/textures/video/* [ Skip ]
+crbug.com/908866 [ android opengles ] conformance/extensions/oes-texture-float-with-image.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/extensions/oes-texture-half-float-with-image.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Failure ]
+
+# Canvas tests fail with missing fonts
+crbug.com/908866 [ android opengles ] conformance/extensions/oes-texture-float-with-canvas.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/extensions/oes-texture-half-float-with-canvas.html [ Failure ]
+crbug.com/908866 [ android opengles ] conformance/textures/canvas/* [ Failure ]
+
+# Misc failures
+crbug.com/2988 [ android opengles ] conformance/context/context-size-change.html [ Failure ]
+crbug.com/2407 [ android opengles ] conformance/misc/uninitialized-test.html [ Failure ]
+crbug.com/908912 [ android opengles ] conformance/renderbuffers/framebuffer-test.html [ Failure ]
+crbug.com/2978 [ android opengles ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Failure ]
+crbug.com/1552 [ android opengles ] WebglExtension_WEBGL_compressed_texture_etc1 [ Failure ]
+
+############
+# ChromeOS #
+############
+
+# ChromeOS: affecting all devices.
+crbug.com/382651 [ chromeos no-passthrough ] conformance/extensions/webgl-depth-texture.html [ Failure ]
+
+# ChromeOS: all Intel except for pinetrail (stumpy, parrot, peppy,...)
+# We will just include pinetrail here for now as we don't want to list
+# every single Intel device ID.
+crbug.com/375556 [ chromeos intel ] conformance/glsl/misc/empty_main.vert.html [ Failure ]
+crbug.com/375556 [ chromeos intel ] conformance/glsl/misc/gl_position_unset.vert.html [ Failure ]
+crbug.com/375556 [ chromeos intel ] conformance/glsl/misc/shaders-with-varyings.html [ Failure ]
+crbug.com/375556 [ chromeos intel no-passthrough ] conformance/renderbuffers/framebuffer-object-attachment.html [ Failure ]
+crbug.com/385361 [ chromeos intel ] conformance/textures/misc/texture-size-limit.html [ Failure ]
+
+# ChromeOS: pinetrail (alex, mario, zgb).
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/attribs/gl-vertex-attrib-render.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/glsl/functions/glsl-function-atan-xy.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/glsl/functions/glsl-function-cos.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/glsl/functions/glsl-function-sin.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/glsl/variables/gl-frontfacing.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/acos/acos_001_to_006.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/asin/asin_001_to_006.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/atan/atan_001_to_008.html [ Failure ]
+crbug.com/378938 [ chromeos intel-0xa011 ] conformance/ogles/GL/build/build_009_to_016.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/control_flow/control_flow_001_to_008.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/cos/cos_001_to_006.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/discard/discard_001_to_002.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/functions/functions_001_to_008.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/functions/functions_065_to_072.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/functions/functions_081_to_088.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/functions/functions_097_to_104.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/functions/functions_105_to_112.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/functions/functions_113_to_120.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/functions/functions_121_to_126.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/log/log_001_to_008.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/log2/log2_001_to_008.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/normalize/normalize_001_to_006.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/ogles/GL/sin/sin_001_to_006.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/rendering/point-size.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/rendering/polygon-offset.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 no-passthrough ] conformance/textures/misc/texture-mips.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 no-passthrough ] conformance/textures/misc/texture-npot.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 no-passthrough ] conformance/textures/misc/texture-npot-video.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/textures/misc/texture-size.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/uniforms/gl-uniform-arrays.html [ Failure ]
+crbug.com/375554 [ chromeos intel-0xa011 ] conformance/uniforms/uniform-default-values.html [ Skip ]
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index 8896e44..7389c09e 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -923,6 +923,7 @@
         ['android', 'opengles'], bug=906724)
     self.Skip('conformance/textures/video/*',
         ['android', 'opengles'], bug=906724)
+
     # Failures with accelerated canvases on nexus5x
     self.Fail('conformance/extensions/oes-texture-float-with-image.html',
         ['android', 'opengles'], bug=957199)
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations_unittest.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations_unittest.py
deleted file mode 100644
index a2e9d60c..0000000
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations_unittest.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# 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 collections
-import itertools
-import unittest
-
-from telemetry.testing import fakes
-
-from gpu_tests import fake_win_amd_gpu_info
-from gpu_tests import test_expectations
-from gpu_tests import webgl_conformance_expectations
-from gpu_tests import webgl2_conformance_expectations
-
-class FakeWindowsPlatform(fakes.FakePlatform):
-  @property
-  def is_host_platform(self):
-    return True
-
-  def GetDeviceTypeName(self):
-    return 'Desktop'
-
-  def GetArchName(self):
-    return 'x86_64'
-
-  def GetOSName(self):
-    return 'win'
-
-  def GetOSVersionName(self):
-    return 'win8'
-
-  def GetOSVersionDetailString(self):
-    # Not sure whether this is accurate.
-    return 'Windows 8.1'
-
-
-class WebGLTestInfo(object):
-  def __init__(self, url):
-    self.name = ('WebglConformance_%s' %
-                 url.replace('/', '_').replace('-', '_').
-                 replace('\\', '_').rpartition('.')[0].replace('.', '_'))
-    self.url = 'file://' + url
-
-Conditions = collections.\
-  namedtuple('Conditions', ['non_gpu', 'vendors', 'devices'])
-
-class WebGLConformanceExpectationsTest(unittest.TestCase):
-  def testGlslConstructVecMatIndexExpectationOnWin(self):
-    possible_browser = fakes.FakePossibleBrowser()
-    browser = possible_browser.Create()
-    browser.platform = FakeWindowsPlatform()
-    browser.returned_system_info = fakes.FakeSystemInfo(
-      gpu_dict=fake_win_amd_gpu_info.FAKE_GPU_INFO)
-    exps = webgl_conformance_expectations.WebGLConformanceExpectations()
-    test_info = WebGLTestInfo(
-      'conformance/glsl/constructors/glsl-construct-vec-mat-index.html')
-    expectation = exps.GetExpectationForTest(
-      browser, test_info.url, test_info.name)
-    self.assertEquals(expectation, 'flaky')
-
-  def testWebGLExpectationsHaveNoCollisions(self):
-    exps = webgl_conformance_expectations.WebGLConformanceExpectations()
-    self.checkConformanceHasNoCollisions(exps)
-
-  def testWebGL2ExpectationsHaveNoCollisions(self):
-    exps = webgl2_conformance_expectations.WebGL2ConformanceExpectations()
-    self.checkConformanceHasNoCollisions(exps)
-
-  def checkConformanceHasNoCollisions(self, conformance):
-    # Checks that no two expectations for the same page can match the
-    # same configuration (wildcards expectations are ok though).
-    # See webgl2_conformance_expectations.py that contains commented out
-    # conflicting expectations that can be used to test this function.
-    expectations = conformance.GetAllNonWildcardExpectations()
-
-    # Extract the conditions of the expectations as a tuple of sets, one
-    # set for each aspect (OS, GPU...) of the expectations.
-    conditions_by_pattern = dict()
-    for e in expectations:
-      conditions_by_pattern[e.pattern] = []
-
-    for e in expectations:
-      # Specifiying 'mac' or 'win' is equivalent to specifying all the
-      # OS's versions
-      os_conditions = e.os_conditions
-      if 'win' in os_conditions:
-        os_conditions += test_expectations.WIN_CONDITIONS
-      if 'mac' in os_conditions:
-        os_conditions += test_expectations.MAC_CONDITIONS
-
-      conditions_by_pattern[e.pattern].append(Conditions(
-        (
-          set(e.os_conditions),
-          set(e.browser_conditions),
-          set(e.asan_conditions),
-          set(e.cmd_decoder_conditions),
-          set(e.angle_conditions),
-        ),
-        set(e.gpu_conditions),
-        set(e.device_id_conditions),
-      ))
-
-    for (pattern, conditions) in conditions_by_pattern.iteritems():
-      for (c1, c2) in itertools.combinations(conditions, 2):
-        # Two conditions for the same page conflict iff we can find a
-        # configuration satisfying both conditions, that is iff for each
-        # aspect, one of the following is true:
-        #  - One of the conditions doesn't specify a requirement for that
-        # aspect, which means we can get a value valid for the other condition
-        #  - Both conditions have requirements but they intersect
-        non_gpu_conflicts = all(
-          [len(aspect1.intersection(aspect2)) != 0 or \
-            len(aspect1) == 0 or len(aspect2) == 0 \
-            for (aspect1, aspect2) in zip(c1.non_gpu, c2.non_gpu)])
-
-        # A GPU configuration matches an expectation if it matches either the
-        # GPU vendor condition or the GPU device condition. This means that
-        # we can have a conflicting configuration if one of the following
-        # is true:
-        # - There are no conditions
-        # - The GPU vendors or the GPU devices intersect
-        # - There is a device of a condition that matches the vendors of
-        # the other condition
-        gpu_conflicts = \
-          len(c1.vendors) + len(c1.devices) == 0 or \
-          len(c2.vendors) + len(c2.devices) == 0 or \
-          len(c1.vendors.intersection(c2.vendors)) != 0 or \
-          len(c1.devices.intersection(c2.devices)) != 0 or \
-          any([vendor in c1.vendors for (vendor, _) in c2.devices]) or \
-          any([vendor in c2.vendors for (vendor, _) in c1.devices])
-
-        conflicts = non_gpu_conflicts and gpu_conflicts
-
-        if conflicts:
-          print "WARNING: Found a conflict for", pattern, " :"
-          print "  ", c1
-          print "  ", c2
-
-          print "  Type:" + (" (non-gpu)" if non_gpu_conflicts else "") + \
-            (" (gpu)" if gpu_conflicts else "")
-        self.assertEquals(conflicts, False)
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
index c7cafbf..82875685 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
@@ -478,6 +478,17 @@
          'webgl-version-%d' % cls._webgl_version])
     return tags
 
+  @classmethod
+  def ExpectationsFiles(cls):
+    assert cls._webgl_version == 1 or cls._webgl_version == 2
+    if cls._webgl_version == 1:
+      file_name = 'webgl_conformance_expectations.txt'
+    else:
+      file_name = 'webgl2_conformance_expectations.txt'
+    return [
+        os.path.join(os.path.dirname(os.path.abspath(__file__)),
+                     'test_expectations', file_name)]
+
 
 def load_tests(loader, tests, pattern):
   del loader, tests, pattern  # Unused.
diff --git a/device/usb/public/cpp/BUILD.gn b/device/usb/public/cpp/BUILD.gn
index ffe8852..167a632 100644
--- a/device/usb/public/cpp/BUILD.gn
+++ b/device/usb/public/cpp/BUILD.gn
@@ -4,6 +4,7 @@
 
 source_set("cpp") {
   sources = [
+    "usb_ids.h",
     "usb_utils.cc",
     "usb_utils.h",
   ]
diff --git a/device/usb/public/cpp/usb_ids.h b/device/usb/public/cpp/usb_ids.h
new file mode 100644
index 0000000..1beb979
--- /dev/null
+++ b/device/usb/public/cpp/usb_ids.h
@@ -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.
+
+#ifndef DEVICE_USB_PUBLIC_CPP_USB_IDS_H_
+#define DEVICE_USB_PUBLIC_CPP_USB_IDS_H_
+
+// This header is just used to expose usb_ids.h to outside users.
+#include "device/usb/usb_ids.h"
+
+#endif  // DEVICE_USB_PUBLIC_CPP_USB_IDS_H_
diff --git a/docs/android_native_libraries.md b/docs/android_native_libraries.md
index 9c13e39..6fe246c9 100644
--- a/docs/android_native_libraries.md
+++ b/docs/android_native_libraries.md
@@ -121,8 +121,10 @@
    * For renderer processes, the OS starts all Monochrome renderer processes by `fork()`ing the WebView zygote rather than the normal application zygote.
      * In this case, RELRO sharing would be redundant since the entire process' memory is shared with the zygote with copy-on-write semantics.
  * For Android Q+ (Trichrome):
-   * TrichromeChrome no longer shares its RELRO data with WebView and no RELRO sharing occurs. TrichromeWebView works the same way as on Android N-P.
-   * TrichromeChrome's renderer processes are no longer `fork()`ed from the WebView zygote. TrichromeWebView works the same way as on Android N-P.
+   * For non-renderer processes, TrichromeChrome no longer shares its RELRO data with WebView and no RELRO sharing occurs. TrichromeWebView works the same way as on Android N-P.
+   * For renderer processes, TrichromeChrome `fork()`s from a chrome-specific app zygote. `libmonochrome.so` is loaded in the zygote before `fork()`.
+     * Similar to O-P, app zygote provides copy-on-write memory semantics so RELRO sharing is redundant.
+   * For renderer processes, TrichromeWebView works the same way as on Android N-P.
 
 ## Library Prefetching
  * During start-up, we `fork()` a process that reads a byte from each page of the library's memory (or just the ordered range of the library).
diff --git a/docs/chromedriver_status.md b/docs/chromedriver_status.md
index d7e09cde..e6f0e41 100644
--- a/docs/chromedriver_status.md
+++ b/docs/chromedriver_status.md
@@ -52,7 +52,7 @@
 | DELETE | /session/{session id}/cookie/{name}                            | Delete Cookie              | Complete           |
 | DELETE | /session/{session id)/cookie                                   | Delete All Cookies         | Complete           |
 | POST   | /session/{session id}/actions                                  | Perform Actions            | Partially Complete | [1897](https://bugs.chromium.org/p/chromedriver/issues/detail?id=1897)
-| DELETE | /session/{session id}/actions                                  | Release Actions            | Partially Complete | [1897](https://bugs.chromium.org/p/chromedriver/issues/detail?id=1897)
+| DELETE | /session/{session id}/actions                                  | Release Actions            | Complete           |
 | POST   | /session/{session id}/alert/dismiss                            | Dismiss Alert              | Complete           |
 | POST   | /session/{session id}/alert/accept                             | Accept Alert               | Complete           |
 | GET    | /session/{session id}/alert/text                               | Get Alert Text             | Complete           |
diff --git a/docs/clang.md b/docs/clang.md
index eda7611b..eb4139f 100644
--- a/docs/clang.md
+++ b/docs/clang.md
@@ -38,7 +38,7 @@
 
 If you're working on the plugin, you can build it locally like so:
 
-1.  Run `./tools/clang/scripts/update.py --force-local-build --without-android`
+1.  Run `./tools/clang/scripts/build.py --without-android`
     to build the plugin.
 1.  Run `ninja -C third_party/llvm-build/Release+Asserts/` to build incrementally.
 1.  Build with clang like described above, but, if you use goma, disable it.
diff --git a/docs/clang_tool_refactoring.md b/docs/clang_tool_refactoring.md
index 107ff8e..b8d31a6 100644
--- a/docs/clang_tool_refactoring.md
+++ b/docs/clang_tool_refactoring.md
@@ -96,7 +96,7 @@
 Synopsis:
 
 ```shell
-tools/clang/scripts/update.py --bootstrap --force-local-build --without-android \
+tools/clang/scripts/build.py --bootstrap --without-android \
   --extra-tools rewrite_to_chrome_style
 ```
 
diff --git a/docs/speed/perf_lab_platforms.md b/docs/speed/perf_lab_platforms.md
index 8e0e4a81..8eda03d4 100644
--- a/docs/speed/perf_lab_platforms.md
+++ b/docs/speed/perf_lab_platforms.md
@@ -6,25 +6,25 @@
 
 ## Android
 
- * [android-go-perf](https://ci.chromium.org/buildbot/chromium.perf/android-go-perf/): Android O.
- * [android-go_webview-perf](https://ci.chromium.org/buildbot/chromium.perf/android-go_webview-perf/): Android OPM1.171019.021.
- * [Android Nexus5 Perf](https://ci.chromium.org/buildbot/chromium.perf/Android%20Nexus5%20Perf/): Android KOT49H.
- * [android-nexus5x-perf](https://ci.chromium.org/buildbot/chromium.perf/android-nexus5x-perf/): Android MMB29Q.
- * [Android Nexus5X WebView Perf](https://ci.chromium.org/buildbot/chromium.perf/Android%20Nexus5X%20WebView%20Perf/): Android AOSP MOB30K.
- * [Android Nexus6 WebView Perf](https://ci.chromium.org/buildbot/chromium.perf/Android%20Nexus6%20WebView%20Perf/): Android AOSP MOB30K.
+ * [android-go-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/android-go-perf): Android O (gobo).
+ * [android-go_webview-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/android-go_webview-perf): Android OPM1.171019.021 (gobo).
+ * [Android Nexus5 Perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/Android%20Nexus5%20Perf): Android KOT49H.
+ * [android-nexus5x-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/android-nexus5x-perf): Android MMB29Q.
+ * [Android Nexus5X WebView Perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/Android%20Nexus5X%20WebView%20Perf): Android AOSP MOB30K.
+ * [Android Nexus6 WebView Perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/Android%20Nexus6%20WebView%20Perf): Android AOSP MOB30K.
 
 ## Linux
 
- * [linux-perf](https://ci.chromium.org/buildbot/chromium.perf/linux-perf/): Ubuntu-14.04, 8 core, NVIDIA Quadro P400.
+ * [linux-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/linux-perf): Ubuntu-14.04, 8 core, NVIDIA Quadro P400.
 
 ## Mac
 
- * [mac-10_12_laptop_low_end-perf](https://ci.chromium.org/buildbot/chromium.perf/mac-10_12_laptop_low_end-perf/): MacBook Air, Core i5 1.8 GHz, 8GB RAM, 128GB SSD, HD Graphics.
- * [mac-10_13_laptop_high_end-perf](https://ci.chromium.org/buildbot/chromium.perf/mac-10_13_laptop_high_end-perf/): MacBook Pro, Core i7 2.8 GHz, 16GB RAM, 256GB SSD, Radeon 55.
+ * [mac-10_12_laptop_low_end-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/mac-10_12_laptop_low_end-perf): MacBook Air, Core i5 1.8 GHz, 8GB RAM, 128GB SSD, HD Graphics.
+ * [mac-10_13_laptop_high_end-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/mac-10_13_laptop_high_end-perf): MacBook Pro, Core i7 2.8 GHz, 16GB RAM, 256GB SSD, Radeon 55.
 
 ## Windows
 
- * [win-10-perf](https://ci.chromium.org/buildbot/chromium.perf/win-10-perf/): Windows Intel HD 630 towers, Core i7-7700 3.6 GHz, 16GB RAM, Intel Kaby Lake HD Graphics 630.
- * [Win 7 Nvidia GPU Perf](https://ci.chromium.org/buildbot/chromium.perf/Win%207%20Nvidia%20GPU%20Perf/): N/A.
- * [Win 7 Perf](https://ci.chromium.org/buildbot/chromium.perf/Win%207%20Perf/): N/A.
+ * [win-10-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/win-10-perf): Windows Intel HD 630 towers, Core i7-7700 3.6 GHz, 16GB RAM, Intel Kaby Lake HD Graphics 630.
+ * [Win 7 Nvidia GPU Perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/Win%207%20Nvidia%20GPU%20Perf): N/A.
+ * [Win 7 Perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/Win%207%20Perf): N/A.
 
diff --git a/docs/sublime_ide.md b/docs/sublime_ide.md
index 9706386..3a0d24e 100644
--- a/docs/sublime_ide.md
+++ b/docs/sublime_ide.md
@@ -182,7 +182,7 @@
 ```json
 {
   "name": "blink",
-  "path": "src/third_party/WebKit",
+  "path": "src/third_party/blink",
 }
 ```
 
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index f9205d3..dd20ca8 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -484,9 +484,7 @@
     "//components/guest_view/browser:test_support",
     "//components/storage_monitor:test_support",
     "//content/test:test_support",
-    "//device/base:mocks",
     "//device/bluetooth:mocks",
-    "//device/usb:test_support",
     "//device/usb/public/cpp:test_support",
     "//extensions:test_support",
     "//extensions/browser:test_support",
diff --git a/extensions/browser/DEPS b/extensions/browser/DEPS
index 840643d..7af2e64 100644
--- a/extensions/browser/DEPS
+++ b/extensions/browser/DEPS
@@ -16,8 +16,7 @@
   "+components/zoom",
   "+content/public/browser",
   "+device/bluetooth",
-  "+device/serial",
-  "+device/usb",
+  "+device/usb/public",
   "+google_apis/gaia",
   "+gpu/config",
   "+grit/extensions_strings.h",
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn
index 937b7b8..133e877 100644
--- a/extensions/browser/api/BUILD.gn
+++ b/extensions/browser/api/BUILD.gn
@@ -106,7 +106,6 @@
   deps += [
     "//components/onc",
     "//components/storage_monitor",
-    "//device/base",
     "//device/bluetooth",
   ]
 
diff --git a/extensions/browser/api/DEPS b/extensions/browser/api/DEPS
index f5d55d7..e197b1f7 100644
--- a/extensions/browser/api/DEPS
+++ b/extensions/browser/api/DEPS
@@ -1,6 +1,6 @@
 include_rules = [
   "+components/device_event_log",
-  "+device/base",
+  "+device/usb/public",
   "+services/device/public",
   "+storage/browser/fileapi",
   "+storage/common/fileapi",
diff --git a/extensions/browser/api/device_permissions_manager.cc b/extensions/browser/api/device_permissions_manager.cc
index f31310d..346f789 100644
--- a/extensions/browser/api/device_permissions_manager.cc
+++ b/extensions/browser/api/device_permissions_manager.cc
@@ -16,9 +16,7 @@
 #include "base/values.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_thread.h"
-#include "device/usb/mojo/type_converters.h"
-#include "device/usb/usb_device.h"
-#include "device/usb/usb_ids.h"
+#include "device/usb/public/cpp/usb_ids.h"
 #include "extensions/browser/api/hid/hid_device_manager.h"
 #include "extensions/browser/api/usb/usb_device_manager.h"
 #include "extensions/browser/extension_host.h"
@@ -352,15 +350,6 @@
 }
 
 scoped_refptr<DevicePermissionEntry> DevicePermissions::FindUsbDeviceEntry(
-    scoped_refptr<device::UsbDevice> device) const {
-  if (!device)
-    return nullptr;
-
-  auto device_info = device::mojom::UsbDeviceInfo::From(*device);
-  return FindUsbDeviceEntry(*device_info);
-}
-
-scoped_refptr<DevicePermissionEntry> DevicePermissions::FindUsbDeviceEntry(
     const device::mojom::UsbDeviceInfo& device) const {
   const auto& ephemeral_device_entry = ephemeral_usb_devices_.find(device.guid);
   if (ephemeral_device_entry != ephemeral_usb_devices_.end()) {
diff --git a/extensions/browser/api/device_permissions_prompt.cc b/extensions/browser/api/device_permissions_prompt.cc
index ec62bbb..48406ad 100644
--- a/extensions/browser/api/device_permissions_prompt.cc
+++ b/extensions/browser/api/device_permissions_prompt.cc
@@ -18,9 +18,6 @@
 #include "content/public/common/service_manager_connection.h"
 #include "device/usb/public/cpp/usb_utils.h"
 #include "device/usb/public/mojom/device_enumeration_options.mojom.h"
-#include "device/usb/usb_device.h"
-#include "device/usb/usb_ids.h"
-#include "device/usb/usb_service.h"
 #include "extensions/browser/api/device_permissions_manager.h"
 #include "extensions/browser/api/usb/usb_device_manager.h"
 #include "extensions/common/extension.h"
diff --git a/extensions/browser/api/hid/hid_device_manager.cc b/extensions/browser/api/hid/hid_device_manager.cc
index f613295..a6d7c12 100644
--- a/extensions/browser/api/hid/hid_device_manager.cc
+++ b/extensions/browser/api/hid/hid_device_manager.cc
@@ -19,7 +19,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/service_manager_connection.h"
-#include "device/base/device_client.h"
 #include "extensions/browser/api/device_permissions_manager.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "extensions/common/permissions/usb_device_permission.h"
diff --git a/extensions/browser/api/printer_provider/BUILD.gn b/extensions/browser/api/printer_provider/BUILD.gn
index 9efce9f3..f591cd5f 100644
--- a/extensions/browser/api/printer_provider/BUILD.gn
+++ b/extensions/browser/api/printer_provider/BUILD.gn
@@ -18,7 +18,8 @@
   ]
 
   deps = [
-    "//device/usb",
+    "//device/usb/public/cpp",
+    "//device/usb/public/mojom",
     "//extensions/common/api",
   ]
 
diff --git a/extensions/browser/api/usb/BUILD.gn b/extensions/browser/api/usb/BUILD.gn
index 912da5f..1e123b6 100644
--- a/extensions/browser/api/usb/BUILD.gn
+++ b/extensions/browser/api/usb/BUILD.gn
@@ -25,7 +25,6 @@
   deps = [
     "//content/public/browser",
     "//content/public/common",
-    "//device/usb",
     "//device/usb/public/cpp",
     "//device/usb/public/mojom",
     "//extensions/common/api",
diff --git a/extensions/browser/api/usb/usb_api.cc b/extensions/browser/api/usb/usb_api.cc
index fe4f0fa..6f5c3ee 100644
--- a/extensions/browser/api/usb/usb_api.cc
+++ b/extensions/browser/api/usb/usb_api.cc
@@ -16,15 +16,10 @@
 #include "base/bind.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/values.h"
-#include "device/base/device_client.h"
-#include "device/usb/mojo/type_converters.h"
 #include "device/usb/public/cpp/usb_utils.h"
 #include "device/usb/public/mojom/device.mojom.h"
 #include "device/usb/public/mojom/device_enumeration_options.mojom.h"
 #include "device/usb/public/mojom/device_manager.mojom.h"
-#include "device/usb/usb_descriptors.h"
-#include "device/usb/usb_device_handle.h"
-#include "device/usb/usb_service.h"
 #include "extensions/browser/api/device_permissions_manager.h"
 #include "extensions/browser/api/device_permissions_prompt.h"
 #include "extensions/browser/api/extensions_api_client.h"
@@ -277,7 +272,7 @@
   }
 }
 
-usb::UsageType ConvertUsageTypeToApi(const device::UsbUsageType& input) {
+usb::UsageType ConvertUsageTypeToApi(const UsbUsageType& input) {
   switch (input) {
     case UsbUsageType::DATA:
       return usb::USAGE_TYPE_DATA;
diff --git a/extensions/browser/guest_view/web_view/web_view_permission_helper.cc b/extensions/browser/guest_view/web_view/web_view_permission_helper.cc
index a5320d16..dad88f7c 100644
--- a/extensions/browser/guest_view/web_view/web_view_permission_helper.cc
+++ b/extensions/browser/guest_view/web_view/web_view_permission_helper.cc
@@ -264,9 +264,9 @@
     int bridge_id,
     const GURL& requesting_frame,
     bool user_gesture,
-    const base::Callback<void(bool)>& callback) {
+    base::OnceCallback<void(bool)> callback) {
   web_view_permission_helper_delegate_->RequestGeolocationPermission(
-      bridge_id, requesting_frame, user_gesture, callback);
+      bridge_id, requesting_frame, user_gesture, std::move(callback));
 }
 
 void WebViewPermissionHelper::CancelGeolocationPermissionRequest(
diff --git a/extensions/browser/guest_view/web_view/web_view_permission_helper.h b/extensions/browser/guest_view/web_view/web_view_permission_helper.h
index 2400bbfe..c3b9014 100644
--- a/extensions/browser/guest_view/web_view/web_view_permission_helper.h
+++ b/extensions/browser/guest_view/web_view/web_view_permission_helper.h
@@ -77,7 +77,7 @@
   void RequestGeolocationPermission(int bridge_id,
                                     const GURL& requesting_frame,
                                     bool user_gesture,
-                                    const base::Callback<void(bool)>& callback);
+                                    base::OnceCallback<void(bool)> callback);
   void CancelGeolocationPermissionRequest(int bridge_id);
 
   void RequestFileSystemPermission(const GURL& url,
diff --git a/extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h b/extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h
index 5f712de3..925bf95 100644
--- a/extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h
+++ b/extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h
@@ -35,7 +35,7 @@
       int bridge_id,
       const GURL& requesting_frame,
       bool user_gesture,
-      const base::Callback<void(bool)>& callback) {}
+      base::OnceCallback<void(bool)> callback) {}
 
   virtual void CancelGeolocationPermissionRequest(int bridge_id) {}
 
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index 1404c71e..00b9082 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -326,8 +326,6 @@
       "//components/version_info",
       "//crypto",
       "//device/bluetooth",
-      "//device/usb",
-      "//device/usb/mojo",
       "//device/usb/public/cpp",
       "//device/usb/public/mojom",
       "//extensions:extensions_resources",
@@ -454,8 +452,6 @@
       "//base/test:test_support",
       "//components/crx_file",
       "//components/version_info:version_info",
-      "//device/usb",
-      "//device/usb/mojo",
       "//device/usb/public/cpp:test_support",
       "//extensions:extensions_resources",
 
diff --git a/extensions/common/DEPS b/extensions/common/DEPS
index 54cb34fc..b81685e 100644
--- a/extensions/common/DEPS
+++ b/extensions/common/DEPS
@@ -3,7 +3,7 @@
   "+components/url_formatter",
   "+components/nacl/common/buildflags.h",
   "+device/bluetooth",  # For BluetoothPermission
-  "+device/usb",
+  "+device/usb/public",
   "+grit/extensions_strings.h",
   "+libxml",
   "+net",
diff --git a/extensions/common/permissions/usb_device_permission.cc b/extensions/common/permissions/usb_device_permission.cc
index edaf197..9a5f556 100644
--- a/extensions/common/permissions/usb_device_permission.cc
+++ b/extensions/common/permissions/usb_device_permission.cc
@@ -13,9 +13,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "device/usb/mojo/type_converters.h"
-#include "device/usb/usb_device.h"
-#include "device/usb/usb_ids.h"
+#include "device/usb/public/cpp/usb_ids.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/features/behavior_feature.h"
 #include "extensions/common/features/feature.h"
@@ -44,17 +42,6 @@
 
 // static
 std::unique_ptr<UsbDevicePermission::CheckParam>
-UsbDevicePermission::CheckParam::ForUsbDevice(const Extension* extension,
-                                              const device::UsbDevice* device) {
-  DCHECK(device);
-  auto device_info = device::mojom::UsbDeviceInfo::From(*device);
-  return CheckParam::ForUsbDeviceAndInterface(
-      extension, *device_info,
-      UsbDevicePermissionData::SPECIAL_VALUE_UNSPECIFIED);
-}
-
-// static
-std::unique_ptr<UsbDevicePermission::CheckParam>
 UsbDevicePermission::CheckParam::ForUsbDevice(
     const Extension* extension,
     const device::mojom::UsbDeviceInfo& device_info) {
diff --git a/extensions/common/permissions/usb_device_permission.h b/extensions/common/permissions/usb_device_permission.h
index f11fea9..f1251af 100644
--- a/extensions/common/permissions/usb_device_permission.h
+++ b/extensions/common/permissions/usb_device_permission.h
@@ -17,10 +17,6 @@
 #include "extensions/common/permissions/set_disjunction_permission.h"
 #include "extensions/common/permissions/usb_device_permission_data.h"
 
-namespace device {
-class UsbDevice;
-}
-
 namespace extensions {
 
 class Extension;
@@ -32,9 +28,6 @@
   struct CheckParam : public APIPermission::CheckParam {
     static std::unique_ptr<CheckParam> ForUsbDevice(
         const Extension* extension,
-        const device::UsbDevice* device);
-    static std::unique_ptr<CheckParam> ForUsbDevice(
-        const Extension* extension,
         const device::mojom::UsbDeviceInfo& device_info);
     // Creates check param that only checks vendor, product and interface ID
     // permission properties. It will accept all interfaceClass properties. For
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn
index 52e89cd..ea56a3e9 100644
--- a/extensions/shell/BUILD.gn
+++ b/extensions/shell/BUILD.gn
@@ -52,9 +52,7 @@
     "//components/version_info",
     "//content",
     "//content/shell:content_shell_lib",
-    "//device/base",
     "//device/bluetooth",
-    "//device/usb",
     "//extensions:extensions_resources",
     "//extensions:shell_and_test_pak",
     "//extensions/browser",
@@ -121,8 +119,6 @@
     "browser/shell_content_browser_client.h",
     "browser/shell_desktop_controller_mac.h",
     "browser/shell_desktop_controller_mac.mm",
-    "browser/shell_device_client.cc",
-    "browser/shell_device_client.h",
     "browser/shell_display_info_provider.cc",
     "browser/shell_display_info_provider.h",
     "browser/shell_extension_host_delegate.cc",
diff --git a/extensions/shell/browser/DEPS b/extensions/shell/browser/DEPS
index e823d16..2629f0c 100644
--- a/extensions/shell/browser/DEPS
+++ b/extensions/shell/browser/DEPS
@@ -20,9 +20,7 @@
   "+content/shell/browser/shell_url_request_context_getter.h",
 
   # For device backend support.
-  "+device/base",
   "+device/bluetooth",
-  "+device/usb",
 
   "+gin",
 
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc
index deb1d6a..d8b731c 100644
--- a/extensions/shell/browser/shell_browser_main_parts.cc
+++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -33,7 +33,6 @@
 #include "extensions/shell/browser/shell_browser_context_keyed_service_factories.h"
 #include "extensions/shell/browser/shell_browser_main_delegate.h"
 #include "extensions/shell/browser/shell_desktop_controller_aura.h"
-#include "extensions/shell/browser/shell_device_client.h"
 #include "extensions/shell/browser/shell_extension_system.h"
 #include "extensions/shell/browser/shell_extension_system_factory.h"
 #include "extensions/shell/browser/shell_extensions_browser_client.h"
@@ -225,8 +224,6 @@
 
   // TODO(jamescook): Initialize user_manager::UserManager.
 
-  device_client_.reset(new ShellDeviceClient);
-
   update_query_params_delegate_.reset(new ShellUpdateQueryParamsDelegate);
   update_client::UpdateQueryParams::SetDelegate(
       update_query_params_delegate_.get());
diff --git a/extensions/shell/browser/shell_browser_main_parts.h b/extensions/shell/browser/shell_browser_main_parts.h
index 33b658b..f6211f5 100644
--- a/extensions/shell/browser/shell_browser_main_parts.h
+++ b/extensions/shell/browser/shell_browser_main_parts.h
@@ -27,7 +27,6 @@
 class DesktopController;
 class ShellBrowserContext;
 class ShellBrowserMainDelegate;
-class ShellDeviceClient;
 class ShellExtensionsClient;
 class ShellExtensionsBrowserClient;
 class ShellExtensionSystem;
@@ -79,7 +78,6 @@
   // The DesktopController outlives ExtensionSystem and context-keyed services.
   std::unique_ptr<DesktopController> desktop_controller_;
 
-  std::unique_ptr<ShellDeviceClient> device_client_;
   std::unique_ptr<ShellExtensionsClient> extensions_client_;
   std::unique_ptr<ShellExtensionsBrowserClient> extensions_browser_client_;
   std::unique_ptr<ShellUpdateQueryParamsDelegate> update_query_params_delegate_;
diff --git a/extensions/shell/browser/shell_device_client.cc b/extensions/shell/browser/shell_device_client.cc
deleted file mode 100644
index 3707901..0000000
--- a/extensions/shell/browser/shell_device_client.cc
+++ /dev/null
@@ -1,25 +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 "extensions/shell/browser/shell_device_client.h"
-
-#include "content/public/browser/browser_thread.h"
-#include "device/usb/usb_service.h"
-
-using content::BrowserThread;
-
-namespace extensions {
-
-ShellDeviceClient::ShellDeviceClient() = default;
-
-ShellDeviceClient::~ShellDeviceClient() = default;
-
-device::UsbService* ShellDeviceClient::GetUsbService() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (!usb_service_)
-    usb_service_ = device::UsbService::Create();
-  return usb_service_.get();
-}
-
-}  // namespace extensions
diff --git a/extensions/shell/browser/shell_device_client.h b/extensions/shell/browser/shell_device_client.h
deleted file mode 100644
index 35eea8d..0000000
--- a/extensions/shell/browser/shell_device_client.h
+++ /dev/null
@@ -1,33 +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 EXTENSIONS_SHELL_BROWSER_SHELL_DEVICE_CLIENT_H_
-#define EXTENSIONS_SHELL_BROWSER_SHELL_DEVICE_CLIENT_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "device/base/device_client.h"
-
-namespace extensions {
-
-// Implementation of device::DeviceClient that returns //device API service
-// singletons appropriate for use within app shell.
-class ShellDeviceClient : device::DeviceClient {
- public:
-  ShellDeviceClient();
-  ~ShellDeviceClient() override;
-
-  // device::DeviceClient implementation
-  device::UsbService* GetUsbService() override;
-
- private:
-  std::unique_ptr<device::UsbService> usb_service_;
-
-  DISALLOW_COPY_AND_ASSIGN(ShellDeviceClient);
-};
-
-}
-
-#endif  // EXTENSIONS_SHELL_BROWSER_SHELL_DEVICE_CLIENT_H_
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 8bc78fe3..ef98bd0 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -449,10 +449,6 @@
       },
       "gl_type": "gl",
       "gl_renderer": ".*Mesa.*",
-      "direct_rendering_version": {
-        "op" : "<",
-        "value": "2.3"
-      },
       "features": [
         "disable_post_sub_buffers_for_onscreen_surfaces"
       ]
diff --git a/headless/lib/browser/headless_permission_manager.cc b/headless/lib/browser/headless_permission_manager.cc
index 46fa0038..5d4d609f 100644
--- a/headless/lib/browser/headless_permission_manager.cc
+++ b/headless/lib/browser/headless_permission_manager.cc
@@ -22,17 +22,17 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) {
   // In headless mode we just pretent the user "closes" any permission prompt,
   // without accepting or denying. Notifications are the exception to this,
   // which are explicitly disabled in Incognito mode.
   if (browser_context_->IsOffTheRecord() &&
       permission == content::PermissionType::NOTIFICATIONS) {
-    callback.Run(blink::mojom::PermissionStatus::DENIED);
+    std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
     return content::PermissionController::kNoPendingOperation;
   }
 
-  callback.Run(blink::mojom::PermissionStatus::ASK);
+  std::move(callback).Run(blink::mojom::PermissionStatus::ASK);
   return content::PermissionController::kNoPendingOperation;
 }
 
@@ -41,13 +41,13 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     bool user_gesture,
-    const base::Callback<
-        void(const std::vector<blink::mojom::PermissionStatus>&)>& callback) {
+    base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)>
+        callback) {
   // In headless mode we just pretent the user "closes" any permission prompt,
   // without accepting or denying.
   std::vector<blink::mojom::PermissionStatus> result(
       permissions.size(), blink::mojom::PermissionStatus::ASK);
-  callback.Run(result);
+  std::move(callback).Run(result);
   return content::PermissionController::kNoPendingOperation;
 }
 
@@ -75,7 +75,7 @@
     content::PermissionType permission,
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
   return content::PermissionController::kNoPendingOperation;
 }
 
diff --git a/headless/lib/browser/headless_permission_manager.h b/headless/lib/browser/headless_permission_manager.h
index 95cadf7..4b83309a 100644
--- a/headless/lib/browser/headless_permission_manager.h
+++ b/headless/lib/browser/headless_permission_manager.h
@@ -21,20 +21,19 @@
   ~HeadlessPermissionManager() override;
 
   // PermissionManager implementation.
-  int RequestPermission(
-      content::PermissionType permission,
-      content::RenderFrameHost* render_frame_host,
-      const GURL& requesting_origin,
-      bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
-      override;
+  int RequestPermission(content::PermissionType permission,
+                        content::RenderFrameHost* render_frame_host,
+                        const GURL& requesting_origin,
+                        bool user_gesture,
+                        base::OnceCallback<void(blink::mojom::PermissionStatus)>
+                            callback) override;
   int RequestPermissions(
       const std::vector<content::PermissionType>& permission,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
-      const base::Callback<
-          void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
+      base::OnceCallback<
+          void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
       override;
   void ResetPermission(content::PermissionType permission,
                        const GURL& requesting_origin,
@@ -51,7 +50,7 @@
       content::PermissionType permission,
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
+      base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
       override;
   void UnsubscribePermissionStatusChange(int subscription_id) override;
 
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor_unittest.cc b/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor_unittest.cc
index 94eba26..792d173 100644
--- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor_unittest.cc
+++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor_unittest.cc
@@ -4,8 +4,6 @@
 
 #include "ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h"
 
-#include "base/base_switches.h"
-#include "base/command_line.h"
 #include "base/macros.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -41,16 +39,6 @@
   GetLocalState()->ClearPref(pref);
   EXPECT_FALSE(
       IOSChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
-
-  // If field trials are forced, metrics should always be disabled, regardless
-  // of the value of the pref.
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kForceFieldTrials);
-  EXPECT_FALSE(
-      IOSChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
-  GetLocalState()->SetBoolean(pref, true);
-  EXPECT_FALSE(
-      IOSChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
 #else
   // Metrics Reporting is never enabled when GOOGLE_CHROME_BUILD is undefined.
   EXPECT_FALSE(
diff --git a/ios/chrome/browser/overlays/overlay_presenter.h b/ios/chrome/browser/overlays/overlay_presenter.h
index 0b676c91..a3c6cfa 100644
--- a/ios/chrome/browser/overlays/overlay_presenter.h
+++ b/ios/chrome/browser/overlays/overlay_presenter.h
@@ -42,9 +42,6 @@
   // OverlayRequestQueueImplObserver:
   void OnRequestAdded(OverlayRequestQueueImpl* queue,
                       OverlayRequest* request) override;
-  void OnRequestRemoved(OverlayRequestQueueImpl* queue,
-                        OverlayRequest* request,
-                        bool frontmost) override;
 
   // WebStateListObserver:
   void WebStateInsertedAt(WebStateList* web_state_list,
diff --git a/ios/chrome/browser/overlays/overlay_presenter.mm b/ios/chrome/browser/overlays/overlay_presenter.mm
index 92c722f5..26608ef7 100644
--- a/ios/chrome/browser/overlays/overlay_presenter.mm
+++ b/ios/chrome/browser/overlays/overlay_presenter.mm
@@ -80,16 +80,6 @@
   }
 }
 
-void OverlayPresenter::OnRequestRemoved(OverlayRequestQueueImpl* queue,
-                                        OverlayRequest* request,
-                                        bool frontmost) {
-  // Only attempt to present overlay UI for the next reqeust for removal of the
-  // frontmost request.
-  if (frontmost) {
-    // TODO:(crbug.com/941745): Trigger presentation for next request in queue.
-  }
-}
-
 #pragma mark - WebStateListObserver
 
 void OverlayPresenter::WebStateInsertedAt(WebStateList* web_state_list,
diff --git a/ios/chrome/browser/overlays/overlay_request_queue_impl.h b/ios/chrome/browser/overlays/overlay_request_queue_impl.h
index 31ef0c2e..d5bbd5e 100644
--- a/ios/chrome/browser/overlays/overlay_request_queue_impl.h
+++ b/ios/chrome/browser/overlays/overlay_request_queue_impl.h
@@ -62,10 +62,6 @@
   // Private constructor called by container.
   OverlayRequestQueueImpl();
 
-  // Notifies the observers of |request|'s removal, with |frontmost| indicating
-  // whether the removed requests was at the front of the queue.
-  void NotifyRequestRemoved(OverlayRequest* request, bool frontmost);
-
   base::ObserverList<OverlayRequestQueueImplObserver>::Unchecked observers_;
   // The queue used to hold the received requests.  Stored as a circular dequeue
   // to allow performant pop events from the front of the queue.
diff --git a/ios/chrome/browser/overlays/overlay_request_queue_impl.mm b/ios/chrome/browser/overlays/overlay_request_queue_impl.mm
index 83cfd99..fb68a2f 100644
--- a/ios/chrome/browser/overlays/overlay_request_queue_impl.mm
+++ b/ios/chrome/browser/overlays/overlay_request_queue_impl.mm
@@ -48,16 +48,12 @@
 
 void OverlayRequestQueueImpl::PopFrontRequest() {
   DCHECK(!requests_.empty());
-  std::unique_ptr<OverlayRequest> popped_request = std::move(requests_.front());
   requests_.pop_front();
-  NotifyRequestRemoved(popped_request.get(), true);
 }
 
 void OverlayRequestQueueImpl::PopBackRequest() {
   DCHECK(!requests_.empty());
-  std::unique_ptr<OverlayRequest> popped_request = std::move(requests_.back());
   requests_.pop_back();
-  NotifyRequestRemoved(popped_request.get(), requests_.empty());
 }
 
 #pragma mark OverlayRequestQueue
@@ -73,12 +69,3 @@
 OverlayRequest* OverlayRequestQueueImpl::front_request() const {
   return requests_.empty() ? nullptr : requests_.front().get();
 }
-
-#pragma mark Private
-
-void OverlayRequestQueueImpl::NotifyRequestRemoved(OverlayRequest* request,
-                                                   bool frontmost) {
-  for (auto& observer : observers_) {
-    observer.OnRequestRemoved(this, request, frontmost);
-  }
-}
diff --git a/ios/chrome/browser/overlays/overlay_request_queue_impl_observer.h b/ios/chrome/browser/overlays/overlay_request_queue_impl_observer.h
index bf8fcd9..dfe7b360 100644
--- a/ios/chrome/browser/overlays/overlay_request_queue_impl_observer.h
+++ b/ios/chrome/browser/overlays/overlay_request_queue_impl_observer.h
@@ -16,13 +16,6 @@
   // Called after |request| has been added to |queue|.
   virtual void OnRequestAdded(OverlayRequestQueueImpl* queue,
                               OverlayRequest* request) {}
-
-  // Called after |request| is removed from |queue|, with |frontmost| indicating
-  // whether the removed request was at the front of the queue.  |request| is
-  // deleted immediately after this callback.
-  virtual void OnRequestRemoved(OverlayRequestQueueImpl* queue,
-                                OverlayRequest* request,
-                                bool frontmost) {}
 };
 
 #endif  // IOS_CHROME_BROWSER_OVERLAYS_OVERLAY_REQUEST_QUEUE_IMPL_OBSERVER_H_
diff --git a/ios/chrome/browser/overlays/overlay_request_queue_impl_unittest.mm b/ios/chrome/browser/overlays/overlay_request_queue_impl_unittest.mm
index 7aaec005..f231793 100644
--- a/ios/chrome/browser/overlays/overlay_request_queue_impl_unittest.mm
+++ b/ios/chrome/browser/overlays/overlay_request_queue_impl_unittest.mm
@@ -24,8 +24,6 @@
   ~MockOverlayRequestQueueImplObserver() {}
 
   MOCK_METHOD2(OnRequestAdded, void(OverlayRequestQueueImpl*, OverlayRequest*));
-  MOCK_METHOD3(OnRequestRemoved,
-               void(OverlayRequestQueueImpl*, OverlayRequest*, bool));
 };
 }  // namespace
 
@@ -75,51 +73,39 @@
 }
 
 // Tests that state is updated correctly and observer callbacks are received
-// when popping the frontmost request.
-TEST_F(OverlayRequestQueueImplTest, PopFrontRequest) {
-  std::unique_ptr<OverlayRequest> first_request =
+// when popping the requests.
+TEST_F(OverlayRequestQueueImplTest, PopRequests) {
+  // Add three requests to the queue.
+  std::unique_ptr<OverlayRequest> passed_request =
       OverlayRequest::CreateWithConfig<FakeOverlayUserData>(nullptr);
-  OverlayRequest* first_request_ptr = first_request.get();
-  std::unique_ptr<OverlayRequest> second_request =
+  OverlayRequest* first_request = passed_request.get();
+  EXPECT_CALL(observer(), OnRequestAdded(queue(), first_request));
+  queue()->AddRequest(std::move(passed_request));
+
+  passed_request =
       OverlayRequest::CreateWithConfig<FakeOverlayUserData>(nullptr);
-  OverlayRequest* second_request_ptr = second_request.get();
+  OverlayRequest* second_request = passed_request.get();
+  EXPECT_CALL(observer(), OnRequestAdded(queue(), second_request));
+  queue()->AddRequest(std::move(passed_request));
 
-  // Add two requests and pop the first.
-  EXPECT_CALL(observer(), OnRequestAdded(queue(), first_request_ptr));
-  queue()->AddRequest(std::move(first_request));
+  passed_request =
+      OverlayRequest::CreateWithConfig<FakeOverlayUserData>(nullptr);
+  OverlayRequest* third_request = passed_request.get();
+  EXPECT_CALL(observer(), OnRequestAdded(queue(), third_request));
+  queue()->AddRequest(std::move(passed_request));
 
-  EXPECT_CALL(observer(), OnRequestAdded(queue(), second_request_ptr));
-  queue()->AddRequest(std::move(second_request));
+  ASSERT_EQ(first_request, queue()->front_request());
+  ASSERT_EQ(3U, queue()->size());
 
-  EXPECT_CALL(observer(), OnRequestRemoved(queue(), first_request_ptr, true));
+  // Pop the first request and check that the size and front request have been
+  // updated.
   queue()->PopFrontRequest();
+  EXPECT_EQ(second_request, queue()->front_request());
+  EXPECT_EQ(2U, queue()->size());
 
-  // Verify that the size and front request have been updated.
-  EXPECT_EQ(second_request_ptr, queue()->front_request());
-  EXPECT_EQ(1U, queue()->size());
-}
-
-// Tests that state is updated correctly and observer callbacks are received
-// when popping the back request.
-TEST_F(OverlayRequestQueueImplTest, PopBackRequest) {
-  std::unique_ptr<OverlayRequest> first_request =
-      OverlayRequest::CreateWithConfig<FakeOverlayUserData>(nullptr);
-  OverlayRequest* first_request_ptr = first_request.get();
-  std::unique_ptr<OverlayRequest> second_request =
-      OverlayRequest::CreateWithConfig<FakeOverlayUserData>(nullptr);
-  OverlayRequest* second_request_ptr = second_request.get();
-
-  // Add two requests and pop the second.
-  EXPECT_CALL(observer(), OnRequestAdded(queue(), first_request_ptr));
-  queue()->AddRequest(std::move(first_request));
-
-  EXPECT_CALL(observer(), OnRequestAdded(queue(), second_request_ptr));
-  queue()->AddRequest(std::move(second_request));
-
-  EXPECT_CALL(observer(), OnRequestRemoved(queue(), second_request_ptr, false));
+  // Pop the third request and check that the second request is still frontmost
+  // and that the size is updated.
   queue()->PopBackRequest();
-
-  // Verify that the size and front request have been updated.
-  EXPECT_EQ(first_request_ptr, queue()->front_request());
+  EXPECT_EQ(second_request, queue()->front_request());
   EXPECT_EQ(1U, queue()->size());
 }
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm
index 66f197a..9e92ade 100644
--- a/ios/chrome/browser/passwords/password_controller_unittest.mm
+++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -985,7 +985,6 @@
   EXPECT_NSEQ(@"[]=, onkeyup=false, onchange=false",
               ExecuteJavaScript(kUsernamePasswordVerificationScript));
 
-  NSString* showAll = @"Show All\u2026";
   // clang-format off
   SuggestionTestData test_data[] = {
     {
@@ -993,7 +992,7 @@
       @[(@"var evt = document.createEvent('Events');"
          "username_.focus();"),
         @""],
-      @[@"user0 ••••••••", @"abc ••••••••", showAll],
+      @[@"user0 ••••••••", @"abc ••••••••"],
       @"[]=, onkeyup=false, onchange=false"
     },
     {
@@ -1001,7 +1000,7 @@
       @[(@"var evt = document.createEvent('Events');"
          "password_.focus();"),
         @""],
-      @[@"user0 ••••••••", @"abc ••••••••", showAll],
+      @[@"user0 ••••••••", @"abc ••••••••"],
       @"[]=, onkeyup=false, onchange=false"
     },
     {
@@ -1009,7 +1008,7 @@
       @[(@"username_.value='ab';"
          "username_.focus();"),
         @""],
-      @[@"user0 ••••••••", @"abc ••••••••", showAll],
+      @[@"user0 ••••••••", @"abc ••••••••"],
       @"ab[]=, onkeyup=false, onchange=false"
     },
   };
@@ -1119,7 +1118,6 @@
                      [suggestion_values addObject:suggestion.value];
                    EXPECT_NSEQ((@[
                                  @"user0 ••••••••", @"abc ••••••••",
-                                 @"Show All\u2026"
                                ]),
                                suggestion_values);
                    block_was_called = YES;
@@ -1484,7 +1482,6 @@
   EXPECT_NSEQ(@"[]=, onkeyup=false, onchange=false",
               ExecuteJavaScript(kUsernamePasswordVerificationScript));
 
-  NSString* showAll = @"Show All\u2026";
   // clang-format off
   SuggestionTestData test_data[] = {
     {
@@ -1492,7 +1489,7 @@
       @[(@"var evt = document.createEvent('Events');"
          "username_.focus();"),
         @""],
-      @[@"user0 ••••••••", @"abc ••••••••", showAll],
+      @[@"user0 ••••••••", @"abc ••••••••"],
       @"[]=, onkeyup=false, onchange=false"
     },
     {
@@ -1500,7 +1497,7 @@
       @[(@"var evt = document.createEvent('Events');"
          "password_.focus();"),
         @""],
-      @[@"user0 ••••••••", @"abc ••••••••", @"Suggest  Password\u2026", showAll],
+      @[@"user0 ••••••••", @"abc ••••••••", @"Suggest  Password\u2026"],
       @"[]=, onkeyup=false, onchange=false"
     },
   };
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
index cccd747..830292b5 100644
--- a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
@@ -1487,49 +1487,6 @@
       performAction:grey_tap()];
 }
 
-// Opens a page with password input, focuses it, clocks "Show All" in the
-// keyboard accessory and verifies that the password list is presented.
-- (void)testOpenSettingsFromManualFallback {
-  // Saving a form is needed for using the "password details" view.
-  SaveExamplePasswordForm();
-
-  const GURL kPasswordURL(web::test::HttpServer::MakeUrl("http://form/"));
-  std::map<GURL, std::string> responses;
-  responses[kPasswordURL] = "<input id='password' type='password'>";
-  web::test::SetUpSimpleHttpServer(responses);
-  CHROME_EG_ASSERT_NO_ERROR([ChromeEarlGrey loadURL:kPasswordURL]);
-
-  // Focus the password field.
-  // Brings up the keyboard by tapping on one of the form's field.
-  [[EarlGrey
-      selectElementWithMatcher:web::WebViewInWebState(
-                                   chrome_test_util::GetCurrentWebState())]
-      performAction:web::WebViewTapElement(
-                        chrome_test_util::GetCurrentWebState(),
-                        [ElementSelector selectorWithElementID:"password"])];
-
-  // Wait until the keyboard shows up before tapping.
-  id<GREYMatcher> showAll = grey_allOf(
-      grey_accessibilityLabel(@"Show All\u2026"), grey_interactable(), nil);
-  GREYCondition* condition =
-      [GREYCondition conditionWithName:@"Wait for the keyboard to show up."
-                                 block:^BOOL {
-                                   NSError* error = nil;
-                                   [[EarlGrey selectElementWithMatcher:showAll]
-                                       assertWithMatcher:grey_notNil()
-                                                   error:&error];
-                                   return (error == nil);
-                                 }];
-  GREYAssert(
-      [condition waitWithTimeout:base::test::ios::kWaitForUIElementTimeout],
-      @"No keyboard with 'Show All' button showed up.");
-  [[EarlGrey selectElementWithMatcher:showAll] performAction:grey_tap()];
-
-  [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabel(
-                                          @"example.com, concrete username")]
-      assertWithMatcher:grey_notNil()];
-}
-
 // Test export flow
 - (void)testExportFlow {
   // Saving a form is needed for exporting passwords.
diff --git a/ios/chrome/browser/ui/settings/search_engine_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/search_engine_table_view_controller_unittest.mm
index 3a1d739..30044d8f 100644
--- a/ios/chrome/browser/ui/settings/search_engine_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/search_engine_table_view_controller_unittest.mm
@@ -69,6 +69,11 @@
     template_url_service_->Load();
   }
 
+  void TearDown() override {
+    DefaultSearchManager::SetFallbackSearchEnginesDisabledForTesting(false);
+    ChromeTableViewControllerTest::TearDown();
+  }
+
   ChromeTableViewController* InstantiateController() override {
     return [[SearchEngineTableViewController alloc]
         initWithBrowserState:chrome_browser_state_.get()];
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index 1c53046..267ae94e 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -261,6 +261,7 @@
     "//ios/testing:ocmock_support",
     "//ios/web/common",
     "//ios/web/navigation",
+    "//ios/web/navigation:block_universal_links_buildflags",
     "//ios/web/navigation:core",
     "//ios/web/navigation:navigation_manager_util",
     "//ios/web/navigation:wk_navigation_util",
@@ -294,6 +295,8 @@
     "navigation/navigation_manager_util_unittest.mm",
     "navigation/nscoder_util_unittest.mm",
     "navigation/wk_based_navigation_manager_impl_unittest.mm",
+    "navigation/wk_navigation_action_policy_util_unittest.mm",
+    "navigation/wk_navigation_action_util_unittest.mm",
     "navigation/wk_navigation_util_unittest.mm",
   ]
 }
@@ -338,7 +341,6 @@
     "net/cookies/wk_http_system_cookie_store_unittest.mm",
     "net/crw_cert_verification_controller_unittest.mm",
     "net/crw_ssl_status_updater_unittest.mm",
-    "net/request_group_util_unittest.mm",
     "net/request_tracker_impl_unittest.mm",
   ]
 }
@@ -520,7 +522,6 @@
     "//ios/web/web_state:wk_web_view_security_util",
     "//ios/web/web_state/js",
     "//ios/web/web_state/js:script_util",
-    "//ios/web/web_state/ui:block_universal_links_buildflags",
     "//ios/web/web_state/ui:crw_context_menu_controller",
     "//ios/web/web_state/ui:crw_wk_script_message_router",
     "//ios/web/web_state/ui:favicon_util",
@@ -544,8 +545,6 @@
     "web_state/ui/html_element_fetch_request_unittest.mm",
     "web_state/ui/web_view_js_utils_unittest.mm",
     "web_state/ui/wk_back_forward_list_item_holder_unittest.mm",
-    "web_state/ui/wk_navigation_action_policy_util_unittest.mm",
-    "web_state/ui/wk_navigation_action_util_unittest.mm",
     "web_state/ui/wk_web_view_configuration_provider_unittest.mm",
   ]
 }
diff --git a/ios/web/navigation/BUILD.gn b/ios/web/navigation/BUILD.gn
index 5f573dc..5a140281 100644
--- a/ios/web/navigation/BUILD.gn
+++ b/ios/web/navigation/BUILD.gn
@@ -2,10 +2,18 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/buildflag_header.gni")
 import("//ios/build/config.gni")
+import("//ios/features.gni")
+
+buildflag_header("block_universal_links_buildflags") {
+  header = "block_universal_links_buildflags.h"
+  flags = [ "BLOCK_UNIVERSAL_LINKS_IN_OFF_THE_RECORD_MODE=$block_universal_links_in_off_the_record_mode" ]
+}
 
 source_set("navigation") {
   deps = [
+    ":block_universal_links_buildflags",
     ":core",
     "//base",
     "//ios/web:core",
@@ -27,6 +35,8 @@
     "crw_session_controller+private_constructors.h",
     "crw_session_controller.h",
     "crw_session_controller.mm",
+    "crw_wk_navigation_handler.h",
+    "crw_wk_navigation_handler.mm",
     "legacy_navigation_manager_impl.h",
     "legacy_navigation_manager_impl.mm",
     "navigation_item_impl_list.h",
@@ -43,6 +53,10 @@
     "time_smoother.h",
     "wk_based_navigation_manager_impl.h",
     "wk_based_navigation_manager_impl.mm",
+    "wk_navigation_action_policy_util.h",
+    "wk_navigation_action_policy_util.mm",
+    "wk_navigation_action_util.h",
+    "wk_navigation_action_util.mm",
   ]
 
   configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/web/navigation/crw_wk_navigation_handler.h b/ios/web/navigation/crw_wk_navigation_handler.h
new file mode 100644
index 0000000..c381b21e
--- /dev/null
+++ b/ios/web/navigation/crw_wk_navigation_handler.h
@@ -0,0 +1,22 @@
+// 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_WEB_NAVIGATION_CRW_WK_NAVIGATION_HANDLER_H_
+#define IOS_WEB_NAVIGATION_CRW_WK_NAVIGATION_HANDLER_H_
+
+#import <UIKit/UIKit.h>
+#import <WebKit/WebKit.h>
+
+// CRWWKNavigationHandler uses this protocol to interact with its owner.
+@protocol CRWWKNavigationHandlerDelegate <NSObject>
+
+@end
+
+// Handler class for WKNavigationDelegate, deals with navigation callbacks from
+// WKWebView and maintains page loading state.
+@interface CRWWKNavigationHandler : NSObject <WKNavigationDelegate>
+
+@end
+
+#endif  // IOS_WEB_NAVIGATION_CRW_WK_NAVIGATION_HANDLER_H_
diff --git a/ios/web/navigation/crw_wk_navigation_handler.mm b/ios/web/navigation/crw_wk_navigation_handler.mm
new file mode 100644
index 0000000..d9fa241
--- /dev/null
+++ b/ios/web/navigation/crw_wk_navigation_handler.mm
@@ -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.
+
+#import "ios/web/navigation/crw_wk_navigation_handler.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation CRWWKNavigationHandler
+
+@end
diff --git a/ios/web/web_state/ui/wk_navigation_action_policy_util.h b/ios/web/navigation/wk_navigation_action_policy_util.h
similarity index 76%
rename from ios/web/web_state/ui/wk_navigation_action_policy_util.h
rename to ios/web/navigation/wk_navigation_action_policy_util.h
index db2510a4..8b2bf820 100644
--- a/ios/web/web_state/ui/wk_navigation_action_policy_util.h
+++ b/ios/web/navigation/wk_navigation_action_policy_util.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_WEB_WEB_STATE_UI_WK_NAVIGATION_ACTION_POLICY_UTIL_H_
-#define IOS_WEB_WEB_STATE_UI_WK_NAVIGATION_ACTION_POLICY_UTIL_H_
+#ifndef IOS_WEB_NAVIGATION_WK_NAVIGATION_ACTION_POLICY_UTIL_H_
+#define IOS_WEB_NAVIGATION_WK_NAVIGATION_ACTION_POLICY_UTIL_H_
 
 #import <WebKit/WebKit.h>
 
@@ -20,4 +20,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_WEB_STATE_UI_WK_NAVIGATION_ACTION_POLICY_UTIL_H_
+#endif  // IOS_WEB_NAVIGATION_WK_NAVIGATION_ACTION_POLICY_UTIL_H_
diff --git a/ios/web/web_state/ui/wk_navigation_action_policy_util.mm b/ios/web/navigation/wk_navigation_action_policy_util.mm
similarity index 91%
rename from ios/web/web_state/ui/wk_navigation_action_policy_util.mm
rename to ios/web/navigation/wk_navigation_action_policy_util.mm
index 3bdfe1c..43c4f64e 100644
--- a/ios/web/web_state/ui/wk_navigation_action_policy_util.mm
+++ b/ios/web/navigation/wk_navigation_action_policy_util.mm
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/web_state/ui/wk_navigation_action_policy_util.h"
+#import "ios/web/navigation/wk_navigation_action_policy_util.h"
 
 #include "base/feature_list.h"
 #include "ios/web/common/features.h"
-#include "ios/web/web_state/ui/block_universal_links_buildflags.h"
+#include "ios/web/navigation/block_universal_links_buildflags.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/web/web_state/ui/wk_navigation_action_policy_util_unittest.mm b/ios/web/navigation/wk_navigation_action_policy_util_unittest.mm
similarity index 93%
rename from ios/web/web_state/ui/wk_navigation_action_policy_util_unittest.mm
rename to ios/web/navigation/wk_navigation_action_policy_util_unittest.mm
index 67848ed..2466549 100644
--- a/ios/web/web_state/ui/wk_navigation_action_policy_util_unittest.mm
+++ b/ios/web/navigation/wk_navigation_action_policy_util_unittest.mm
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/web_state/ui/wk_navigation_action_policy_util.h"
+#import "ios/web/navigation/wk_navigation_action_policy_util.h"
 
 #import <WebKit/WebKit.h>
 
 #include "base/test/scoped_feature_list.h"
 #include "ios/web/common/features.h"
-#include "ios/web/web_state/ui/block_universal_links_buildflags.h"
+#include "ios/web/navigation/block_universal_links_buildflags.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
diff --git a/ios/web/web_state/ui/wk_navigation_action_util.h b/ios/web/navigation/wk_navigation_action_util.h
similarity index 87%
rename from ios/web/web_state/ui/wk_navigation_action_util.h
rename to ios/web/navigation/wk_navigation_action_util.h
index 4158ee4..0570fbb 100644
--- a/ios/web/web_state/ui/wk_navigation_action_util.h
+++ b/ios/web/navigation/wk_navigation_action_util.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_WEB_WEB_STATE_UI_WK_NAVIGATION_ACTION_UTIL_H_
-#define IOS_WEB_WEB_STATE_UI_WK_NAVIGATION_ACTION_UTIL_H_
+#ifndef IOS_WEB_NAVIGATION_WK_NAVIGATION_ACTION_UTIL_H_
+#define IOS_WEB_NAVIGATION_WK_NAVIGATION_ACTION_UTIL_H_
 
 @class WKNavigationAction;
 @class NSString;
@@ -37,4 +37,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_WEB_STATE_UI_WK_NAVIGATION_ACTION_UTIL_H_
+#endif  // IOS_WEB_NAVIGATION_WK_NAVIGATION_ACTION_UTIL_H_
diff --git a/ios/web/web_state/ui/wk_navigation_action_util.mm b/ios/web/navigation/wk_navigation_action_util.mm
similarity index 95%
rename from ios/web/web_state/ui/wk_navigation_action_util.mm
rename to ios/web/navigation/wk_navigation_action_util.mm
index a6117e70..ea0f0d1 100644
--- a/ios/web/web_state/ui/wk_navigation_action_util.mm
+++ b/ios/web/navigation/wk_navigation_action_util.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/web_state/ui/wk_navigation_action_util.h"
+#import "ios/web/navigation/wk_navigation_action_util.h"
 
 #import <WebKit/WebKit.h>
 
@@ -65,9 +65,8 @@
 NavigationActionInitiationType GetNavigationActionInitiationTypeWithVoiceOverOn(
     NSString* action_description) {
   NSRegularExpression* position_regex = [NSRegularExpression
-      regularExpressionWithPattern:
-          @"\\bposition x = ([0-9]+\\.?[0-9]+) y = "
-          @"([0-9]+\\.?[0-9]+)\\b"
+      regularExpressionWithPattern:@"\\bposition x = ([0-9]+\\.?[0-9]+) y = "
+                                   @"([0-9]+\\.?[0-9]+)\\b"
                            options:NSRegularExpressionCaseInsensitive
                              error:nil];
   NSTextCheckingResult* position_match_result = [position_regex
diff --git a/ios/web/web_state/ui/wk_navigation_action_util_unittest.mm b/ios/web/navigation/wk_navigation_action_util_unittest.mm
similarity index 98%
rename from ios/web/web_state/ui/wk_navigation_action_util_unittest.mm
rename to ios/web/navigation/wk_navigation_action_util_unittest.mm
index 94ec5197..5be57f0 100644
--- a/ios/web/web_state/ui/wk_navigation_action_util_unittest.mm
+++ b/ios/web/navigation/wk_navigation_action_util_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/web_state/ui/wk_navigation_action_util.h"
+#import "ios/web/navigation/wk_navigation_action_util.h"
 
 #import <WebKit/WebKit.h>
 
diff --git a/ios/web/net/BUILD.gn b/ios/web/net/BUILD.gn
index 1d7f111..867e94ea 100644
--- a/ios/web/net/BUILD.gn
+++ b/ios/web/net/BUILD.gn
@@ -29,8 +29,6 @@
     "crw_cert_verification_controller.mm",
     "crw_ssl_status_updater.h",
     "crw_ssl_status_updater.mm",
-    "request_group_util.h",
-    "request_group_util.mm",
     "request_tracker_impl.h",
     "request_tracker_impl.mm",
   ]
diff --git a/ios/web/net/request_group_util.h b/ios/web/net/request_group_util.h
deleted file mode 100644
index 071f51f3..0000000
--- a/ios/web/net/request_group_util.h
+++ /dev/null
@@ -1,59 +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 IOS_WEB_NET_REQUEST_GROUP_UTIL_H_
-#define IOS_WEB_NET_REQUEST_GROUP_UTIL_H_
-
-@class NSString;
-@class NSURL;
-@class NSURLRequest;
-
-// Request group IDs are internally used by the web layer to associate network
-// requests to RequestTracker instances, and in turn, to WebState instances.
-// The ID can be added to the user-agent string by UIWebView in most cases and
-// then extracted by the network layer.
-// However, when using non-standard schemes, UIWebView does not add the
-// "User-Agent" HTTP header to the requests. The workaround for this case is to
-// add the ID directly in the URL of the main request (which is the only request
-// accessible from the UIWebView delegate).
-
-namespace web {
-
-// Generates a request-group ID.
-NSString* GenerateNewRequestGroupID();
-
-// Extracts the requestGroupID embedded in a User-Agent string or nil if a
-// requestGroupID cannot be located.
-NSString* ExtractRequestGroupIDFromUserAgent(NSString* user_agent);
-
-// Returns a new user agent, which is the result of the encoding of
-// |request_group_id| in |base_user_agent|. The request group ID can be later
-// extracted with ExtractRequestGroupIDFromUserAgent().
-// If request_group_id is nil, returns base_user_agent.
-NSString* AddRequestGroupIDToUserAgent(NSString* base_user_agent,
-                                       NSString* request_group_id);
-
-// Extracts the requestGroupID embedded in a NSURL or nil if a requestGroupID
-// cannot be located.
-NSString* ExtractRequestGroupIDFromURL(NSURL* url);
-
-// Returns a new user agent, which is the result of the encoding of
-// |request_group_id| in |base_url|. The request group ID can be later extracted
-// with ExtractRequestGroupIDFromURL().
-NSURL* AddRequestGroupIDToURL(NSURL* base_url, NSString* request_group_id);
-
-// Extracts the request group ID from |request| by retrieving it from the
-// user-agent if possible, and from the parent URL otherwise.
-// The ID can only be retrived from the parent URL if its scheme is
-// |application_scheme|.
-// The reason why the |application_scheme| case is different is because
-// UIWebView does not provide a "User-Agent" HTTP header for these requests.
-// The ID is then encoded in the URL of the main request, and thus sub-requests
-// have to look in their parent URL for the ID.
-NSString* ExtractRequestGroupIDFromRequest(NSURLRequest* request,
-                                           NSString* application_scheme);
-
-}  // namespace web
-
-#endif  // IOS_WEB_NET_REQUEST_GROUP_UTIL_H_
diff --git a/ios/web/net/request_group_util.mm b/ios/web/net/request_group_util.mm
deleted file mode 100644
index 51eeddb..0000000
--- a/ios/web/net/request_group_util.mm
+++ /dev/null
@@ -1,119 +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.
-
-#import "ios/web/net/request_group_util.h"
-
-#import <Foundation/Foundation.h>
-
-#include "base/base64.h"
-#include "base/logging.h"
-#include "base/rand_util.h"
-#include "base/strings/sys_string_conversions.h"
-#import "net/base/mac/url_conversions.h"
-#include "url/gurl.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-// Minimum length for a request group ID. A shorter string is considered as an
-// invalid ID.
-const int kMinimumIDLength = 5;
-}
-
-namespace web {
-
-// Generates a request-group ID used to correlate web requests with the embedder
-// that triggered it. It is important that the return value should not be unique
-// for different users. See crbug/355613 for context.
-NSString* GenerateNewRequestGroupID() {
-  const unsigned int kGroupSize = 1000;
-  static unsigned long count = 0;
-  static unsigned int offset = base::RandInt(0, kGroupSize - 1);
-
-  unsigned long current = count++;
-  if (current < kGroupSize)
-    current = (current + offset) % kGroupSize;
-
-  // The returned string must have a minimum of kMinimumIDLength characters, and
-  // no spaces.
-  // TODO(blundell): Develop a long-term solution to this problem.
-  // crbug.com/329243
-  return [NSString stringWithFormat:@"%06lu", current];
-}
-
-NSString* ExtractRequestGroupIDFromUserAgent(NSString* user_agent) {
-  if (![user_agent length])
-    return nil;
-
-  // The request_group_id is wrapped by parenthesis in the last space-delimited
-  // fragment.
-  NSString* fragment =
-      [[user_agent componentsSeparatedByString:@" "] lastObject];
-  NSString* request_group_id =
-      [fragment hasPrefix:@"("] && [fragment hasSuffix:@")"]
-          ? [fragment substringWithRange:NSMakeRange(1, [fragment length] - 2)]
-          : nil;
-  // GTLService constructs user agents that end with "(gzip)". To avoid these
-  // getting treated as having the request_group_id "gzip", short-circuit out if
-  // the request_group_id is not long enough to be a valid request_group_id (all
-  // valid request_group_id are at least kMinimumIDLength characters long).
-  // TODO(blundell): Develop a long-term solution to this problem.
-  // crbug.com/329243
-  if ([request_group_id length] < kMinimumIDLength)
-    return nil;
-  return request_group_id;
-}
-
-NSString* AddRequestGroupIDToUserAgent(NSString* base_user_agent,
-                                       NSString* request_group_id) {
-  if (!request_group_id)
-    return base_user_agent;
-  // TODO(blundell): Develop a long-term solution to this problem.
-  // crbug.com/329243
-  DCHECK([request_group_id length] >= kMinimumIDLength);
-  return
-      [NSString stringWithFormat:@"%@ (%@)", base_user_agent, request_group_id];
-}
-
-NSString* ExtractRequestGroupIDFromURL(NSURL* url) {
-  GURL gurl = net::GURLWithNSURL(url);
-  if (!gurl.has_username())
-    return nil;
-
-  std::string request_group_id_as_string;
-  if (base::Base64Decode(gurl.username(), &request_group_id_as_string))
-    return base::SysUTF8ToNSString(request_group_id_as_string);
-
-  return nil;
-}
-
-NSURL* AddRequestGroupIDToURL(NSURL* base_url, NSString* request_group_id) {
-  GURL url = net::GURLWithNSURL(base_url);
-  std::string base64RequestGroupID;
-  base::Base64Encode(base::SysNSStringToUTF8(request_group_id),
-                     &base64RequestGroupID);
-  GURL::Replacements replacements;
-  replacements.SetUsernameStr(base64RequestGroupID);
-  url = url.ReplaceComponents(replacements);
-  return net::NSURLWithGURL(url);
-}
-
-NSString* ExtractRequestGroupIDFromRequest(NSURLRequest* request,
-                                           NSString* application_scheme) {
-  NSString* user_agent =
-      [[request allHTTPHeaderFields] objectForKey:@"User-Agent"];
-  NSString* request_group_id = ExtractRequestGroupIDFromUserAgent(user_agent);
-  if (request_group_id)
-    return request_group_id;
-  if (application_scheme &&
-      [[request.mainDocumentURL scheme]
-          caseInsensitiveCompare:application_scheme] == NSOrderedSame) {
-    return ExtractRequestGroupIDFromURL(request.mainDocumentURL);
-  }
-  return nil;
-}
-
-}  // namespace web
diff --git a/ios/web/net/request_group_util_unittest.mm b/ios/web/net/request_group_util_unittest.mm
deleted file mode 100644
index dd25c6e..0000000
--- a/ios/web/net/request_group_util_unittest.mm
+++ /dev/null
@@ -1,38 +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.
-
-#import "ios/web/net/request_group_util.h"
-
-#import <Foundation/Foundation.h>
-#include <stddef.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 RequestGroupUtilTest = PlatformTest;
-
-// Checks that all newly generated groupID are unique and that there are no
-// duplicates.
-TEST_F(RequestGroupUtilTest, RequestGroupID) {
-  NSMutableSet* set = [[NSMutableSet alloc] init];
-  const size_t kGenerated = 2000;
-  for (size_t i = 0; i < kGenerated; ++i)
-    [set addObject:web::GenerateNewRequestGroupID()];
-  EXPECT_EQ(kGenerated, [set count]);
-}
-
-// Tests that the ExtractRequestGroupIDFromUserAgent function behaves as
-// intended.
-TEST_F(RequestGroupUtilTest, ExtractRequestGroupIDFromUserAgent) {
-  EXPECT_FALSE(web::ExtractRequestGroupIDFromUserAgent(nil));
-  EXPECT_FALSE(web::ExtractRequestGroupIDFromUserAgent(
-      @"Lynx/2.8.1pre.9 libwww-FM/2.14"));
-  EXPECT_FALSE(web::ExtractRequestGroupIDFromUserAgent(@"    "));
-  EXPECT_TRUE([web::ExtractRequestGroupIDFromUserAgent(@"Mozilla/3.04 (WinNT)")
-      isEqualToString:@"WinNT"]);
-}
diff --git a/ios/web/public/global_state/ios_global_state.mm b/ios/web/public/global_state/ios_global_state.mm
index cf45518..862ac71 100644
--- a/ios/web/public/global_state/ios_global_state.mm
+++ b/ios/web/public/global_state/ios_global_state.mm
@@ -37,12 +37,12 @@
 
   return base::ThreadPool::InitParams(
       base::ThreadGroupParams(
-          base::RecommendedMaxNumberOfThreadsInPool(
+          base::RecommendedMaxNumberOfThreadsInThreadGroup(
               kMinBackgroundThreads, kMaxBackgroundThreads,
               kCoreMultiplierBackgroundThreads, kOffsetBackgroundThreads),
           base::TimeDelta::FromSeconds(kReclaimTimeBackground)),
       base::ThreadGroupParams(
-          base::RecommendedMaxNumberOfThreadsInPool(
+          base::RecommendedMaxNumberOfThreadsInThreadGroup(
               kMinForegroundThreads, kMaxForegroundThreads,
               kCoreMultiplierForegroundThreads, kOffsetForegroundThreads),
           base::TimeDelta::FromSeconds(kReclaimTimeForeground)));
diff --git a/ios/web/web_state/ui/BUILD.gn b/ios/web/web_state/ui/BUILD.gn
index 6a3b54a..8bd69767 100644
--- a/ios/web/web_state/ui/BUILD.gn
+++ b/ios/web/web_state/ui/BUILD.gn
@@ -2,18 +2,10 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/buildflag_header.gni")
 import("//ios/build/config.gni")
-import("//ios/features.gni")
-
-buildflag_header("block_universal_links_buildflags") {
-  header = "block_universal_links_buildflags.h"
-  flags = [ "BLOCK_UNIVERSAL_LINKS_IN_OFF_THE_RECORD_MODE=$block_universal_links_in_off_the_record_mode" ]
-}
 
 source_set("ui") {
   deps = [
-    ":block_universal_links_buildflags",
     ":crw_context_menu_controller",
     ":crw_web_view_navigation_proxy",
     ":crw_wk_script_message_router",
@@ -66,10 +58,6 @@
     "web_kit_constants.h",
     "wk_back_forward_list_item_holder.h",
     "wk_back_forward_list_item_holder.mm",
-    "wk_navigation_action_policy_util.h",
-    "wk_navigation_action_policy_util.mm",
-    "wk_navigation_action_util.h",
-    "wk_navigation_action_util.mm",
     "wk_security_origin_util.h",
     "wk_security_origin_util.mm",
   ]
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 0f0325e..453e943 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -58,6 +58,8 @@
 #import "ios/web/navigation/navigation_item_impl.h"
 #import "ios/web/navigation/navigation_manager_impl.h"
 #include "ios/web/navigation/navigation_manager_util.h"
+#import "ios/web/navigation/wk_navigation_action_policy_util.h"
+#import "ios/web/navigation/wk_navigation_action_util.h"
 #import "ios/web/navigation/wk_navigation_util.h"
 #include "ios/web/net/cert_host_pair.h"
 #import "ios/web/net/crw_cert_verification_controller.h"
@@ -102,8 +104,6 @@
 #import "ios/web/web_state/ui/favicon_util.h"
 #include "ios/web/web_state/ui/web_kit_constants.h"
 #import "ios/web/web_state/ui/wk_back_forward_list_item_holder.h"
-#import "ios/web/web_state/ui/wk_navigation_action_policy_util.h"
-#import "ios/web/web_state/ui/wk_navigation_action_util.h"
 #import "ios/web/web_state/ui/wk_security_origin_util.h"
 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
 #import "ios/web/web_state/web_frame_impl.h"
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm
index 05aeabd..29cb439 100644
--- a/ios/web/web_state/ui/crw_web_controller_unittest.mm
+++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -22,6 +22,7 @@
 #import "ios/web/navigation/crw_session_controller.h"
 #import "ios/web/navigation/navigation_item_impl.h"
 #import "ios/web/navigation/navigation_manager_impl.h"
+#import "ios/web/navigation/wk_navigation_action_policy_util.h"
 #import "ios/web/public/crw_navigation_item_storage.h"
 #import "ios/web/public/crw_session_storage.h"
 #import "ios/web/public/download/download_controller.h"
@@ -52,7 +53,6 @@
 #import "ios/web/web_state/ui/crw_web_controller.h"
 #import "ios/web/web_state/ui/crw_web_controller_container_view.h"
 #import "ios/web/web_state/ui/web_view_js_utils.h"
-#import "ios/web/web_state/ui/wk_navigation_action_policy_util.h"
 #import "ios/web/web_state/web_state_impl.h"
 #import "ios/web/web_state/wk_web_view_security_util.h"
 #import "net/base/mac/url_conversions.h"
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc
index 55811596..c3c4d03 100644
--- a/media/renderers/video_resource_updater.cc
+++ b/media/renderers/video_resource_updater.cc
@@ -782,7 +782,8 @@
   gpu::SyncToken sync_token = video_frame->UpdateReleaseSyncToken(&client);
 
   auto transferable_resource = viz::TransferableResource::MakeGL(
-      hardware_resource->mailbox(), GL_LINEAR, GL_TEXTURE_2D, sync_token);
+      hardware_resource->mailbox(), GL_LINEAR, GL_TEXTURE_2D, sync_token,
+      output_plane_resource_size, false /* is_overlay_candidate */);
   transferable_resource.color_space = resource_color_space;
   transferable_resource.format = copy_resource_format;
   external_resources->resources.push_back(std::move(transferable_resource));
@@ -842,7 +843,7 @@
       const size_t height =
           VideoFrame::Rows(i, video_frame->format(), coded_size.height());
       const gfx::Size plane_size(width, height);
-      auto transfer_resource = viz::TransferableResource::MakeGLOverlay(
+      auto transfer_resource = viz::TransferableResource::MakeGL(
           mailbox_holder.mailbox, GL_LINEAR, mailbox_holder.texture_target,
           mailbox_holder.sync_token, plane_size,
           video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY));
@@ -1034,7 +1035,7 @@
                      ? raster_context_provider_->ContextGL()
                      : context_provider_->ContextGL();
       GenerateCompositorSyncToken(gl, &sync_token);
-      transferable_resource = viz::TransferableResource::MakeGLOverlay(
+      transferable_resource = viz::TransferableResource::MakeGL(
           hardware_resource->mailbox(), GL_LINEAR,
           hardware_resource->texture_target(), sync_token,
           hardware_resource->resource_size(),
@@ -1188,7 +1189,7 @@
 
   for (size_t i = 0; i < plane_resources.size(); ++i) {
     HardwarePlaneResource* plane_resource = plane_resources[i]->AsHardware();
-    auto transferable_resource = viz::TransferableResource::MakeGLOverlay(
+    auto transferable_resource = viz::TransferableResource::MakeGL(
         plane_resource->mailbox(), GL_LINEAR, plane_resource->texture_target(),
         sync_token, plane_resource->resource_size(),
         plane_resource->overlay_candidate());
diff --git a/net/base/escape.cc b/net/base/escape.cc
index 2245fc5..b37078cb 100644
--- a/net/base/escape.cc
+++ b/net/base/escape.cc
@@ -487,7 +487,7 @@
   return base::UTF8ToUTF16WithAdjustments(text, adjustments);
 }
 
-void UnescapeBinaryURLComponent(base::StringPiece escaped_text,
+void UnescapeBinaryURLComponent(const std::string& escaped_text,
                                 UnescapeRule::Type rules,
                                 std::string* unescaped_text) {
   // Only NORMAL and REPLACE_PLUS_WITH_SPACE are supported.
diff --git a/net/base/escape.h b/net/base/escape.h
index 151dab3..8e86e61f 100644
--- a/net/base/escape.h
+++ b/net/base/escape.h
@@ -150,11 +150,11 @@
 //
 // Only the NORMAL and REPLACE_PLUS_WITH_SPACE rules are allowed.
 // |escaped_text| and |unescaped_text| can be the same string.
-NET_EXPORT void UnescapeBinaryURLComponent(base::StringPiece escaped_text,
+NET_EXPORT void UnescapeBinaryURLComponent(const std::string& escaped_text,
                                            UnescapeRule::Type rules,
                                            std::string* unescaped_text);
 NET_EXPORT inline void UnescapeBinaryURLComponent(
-    base::StringPiece escaped_text,
+    const std::string& escaped_text,
     std::string* unescaped_text) {
   UnescapeBinaryURLComponent(escaped_text, UnescapeRule::NORMAL,
                              unescaped_text);
diff --git a/net/quic/platform/impl/quic_flags_impl.h b/net/quic/platform/impl/quic_flags_impl.h
index 6ec16b7b..fbc9a93 100644
--- a/net/quic/platform/impl/quic_flags_impl.h
+++ b/net/quic/platform/impl/quic_flags_impl.h
@@ -46,27 +46,7 @@
   return flag;
 }
 
-inline void SetQuicFlagImpl(bool* f, bool v) {
-  *f = v;
-}
-inline void SetQuicFlagImpl(int32_t* f, int32_t v) {
-  *f = v;
-}
-inline void SetQuicFlagImpl(uint32_t* f, uint32_t v) {
-  *f = v;
-}
-inline void SetQuicFlagImpl(int64_t* f, int64_t v) {
-  *f = v;
-}
-inline void SetQuicFlagImpl(uint64_t* f, uint64_t v) {
-  *f = v;
-}
-inline void SetQuicFlagImpl(double* f, double v) {
-  *f = v;
-}
-inline void SetQuicFlagImpl(std::string* f, const std::string& v) {
-  *f = v;
-}
+#define SetQuicFlagImpl(flag, value) ((flag) = (value))
 
 namespace quic {
 
@@ -207,10 +187,10 @@
 
 #define GetQuicReloadableFlagImpl(flag) GetQuicFlag(RELOADABLE_FLAG(flag))
 #define SetQuicReloadableFlagImpl(flag, value) \
-  SetQuicFlag(&RELOADABLE_FLAG(flag), value)
+  SetQuicFlag(RELOADABLE_FLAG(flag), value)
 #define GetQuicRestartFlagImpl(flag) GetQuicFlag(RESTART_FLAG(flag))
 #define SetQuicRestartFlagImpl(flag, value) \
-  SetQuicFlag(&RESTART_FLAG(flag), value)
+  SetQuicFlag(RESTART_FLAG(flag), value)
 
 }  // namespace quic
 #endif  // NET_QUIC_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
diff --git a/net/quic/platform/impl/quic_flags_test.cc b/net/quic/platform/impl/quic_flags_test.cc
index aeb1599a..ce96ce91 100644
--- a/net/quic/platform/impl/quic_flags_test.cc
+++ b/net/quic/platform/impl/quic_flags_test.cc
@@ -77,7 +77,7 @@
 TEST_F(QuicCommandLineFlagTest, BoolFlag) {
   for (const char* s :
        {"--foo", "--foo=1", "--foo=t", "--foo=True", "--foo=Y", "--foo=yes"}) {
-    SetQuicFlag(&FLAGS_foo, false);
+    SetQuicFlag(FLAGS_foo, false);
     const char* argv[]{"argv0", s};
     auto parse_result = QuicParseCommandLineFlagsForTest(
         "usage message", base::size(argv), argv);
@@ -88,7 +88,7 @@
 
   for (const char* s :
        {"--foo=0", "--foo=f", "--foo=False", "--foo=N", "--foo=no"}) {
-    SetQuicFlag(&FLAGS_foo, true);
+    SetQuicFlag(FLAGS_foo, true);
     const char* argv[]{"argv0", s};
     auto parse_result = QuicParseCommandLineFlagsForTest(
         "usage message", base::size(argv), argv);
@@ -98,7 +98,7 @@
   }
 
   for (const char* s : {"--foo=7", "--foo=abc", "--foo=trueish"}) {
-    SetQuicFlag(&FLAGS_foo, false);
+    SetQuicFlag(FLAGS_foo, false);
     const char* argv[]{"argv0", s};
 
     testing::internal::CaptureStderr();
@@ -117,7 +117,7 @@
 
 TEST_F(QuicCommandLineFlagTest, Int32Flag) {
   for (const int i : {-1, 0, 100, 38239832}) {
-    SetQuicFlag(&FLAGS_bar, 0);
+    SetQuicFlag(FLAGS_bar, 0);
     std::string flag_str = base::StringPrintf("--bar=%d", i);
     const char* argv[]{"argv0", flag_str.c_str()};
     auto parse_result = QuicParseCommandLineFlagsForTest(
@@ -128,7 +128,7 @@
   }
 
   for (const char* s : {"--bar", "--bar=a", "--bar=9999999999999"}) {
-    SetQuicFlag(&FLAGS_bar, 0);
+    SetQuicFlag(FLAGS_bar, 0);
     const char* argv[]{"argv0", s};
 
     testing::internal::CaptureStderr();
@@ -147,7 +147,7 @@
 
 TEST_F(QuicCommandLineFlagTest, StringFlag) {
   {
-    SetQuicFlag(&FLAGS_baz, "whee");
+    SetQuicFlag(FLAGS_baz, "whee");
     const char* argv[]{"argv0", "--baz"};
     auto parse_result = QuicParseCommandLineFlagsForTest(
         "usage message", base::size(argv), argv);
@@ -157,7 +157,7 @@
   }
 
   for (const char* s : {"", "12345", "abcdefg"}) {
-    SetQuicFlag(&FLAGS_baz, "qux");
+    SetQuicFlag(FLAGS_baz, "qux");
     std::string flag_str = base::StrCat({"--baz=", s});
     const char* argv[]{"argv0", flag_str.c_str()};
     auto parse_result = QuicParseCommandLineFlagsForTest(
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h
index 97b8d68..dbb979e 100644
--- a/net/quic/quic_flags_list.h
+++ b/net/quic/quic_flags_list.h
@@ -241,12 +241,6 @@
           FLAGS_quic_reloadable_flag_quic_bbr_startup_rate_reduction,
           false)
 
-// If true, QuicPacketCreator::SetTransmissionType will set the transmission
-// type of the next successfully added frame.
-QUIC_FLAG(bool,
-          FLAGS_quic_reloadable_flag_quic_set_transmission_type_for_next_frame,
-          true)
-
 // If true, log leaf cert subject name into warning log.
 QUIC_FLAG(bool,
           FLAGS_quic_reloadable_flag_quic_log_cert_name_for_empty_sct,
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index 97d484d..42ca6bb2 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -169,151 +169,27 @@
     bool is_websocket,
     const NetLogWithSource& net_log) {
   auto it = LookupAvailableSessionByKey(key);
-  if (it != available_sessions_.end() &&
-      (!is_websocket || it->second->support_websocket())) {
-    if (key == it->second->spdy_session_key()) {
-      UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING,
-                                SPDY_SESSION_GET_MAX);
-      net_log.AddEvent(
-          NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION,
-          it->second->net_log().source().ToEventParametersCallback());
-      return it->second;
-    }
-
-    if (enable_ip_based_pooling) {
-      UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
-                                FOUND_EXISTING_FROM_IP_POOL,
-                                SPDY_SESSION_GET_MAX);
-      net_log.AddEvent(
-          NetLogEventType::
-              HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
-          it->second->net_log().source().ToEventParametersCallback());
-      return it->second;
-    }
+  if (it == available_sessions_.end() ||
+      (is_websocket && !it->second->support_websocket())) {
     return base::WeakPtr<SpdySession>();
   }
 
-  if (!enable_ip_based_pooling)
-    return base::WeakPtr<SpdySession>();
+  if (key == it->second->spdy_session_key()) {
+    UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING,
+                              SPDY_SESSION_GET_MAX);
+    net_log.AddEvent(
+        NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION,
+        it->second->net_log().source().ToEventParametersCallback());
+    return it->second;
+  }
 
-  // Look up IP addresses from resolver cache.
-  HostResolver::ResolveHostParameters parameters;
-  parameters.source = HostResolverSource::LOCAL_ONLY;
-  std::unique_ptr<HostResolver::ResolveHostRequest> request =
-      resolver_->CreateRequest(key.host_port_pair(), net_log, parameters);
-
-  int rv = request->Start(base::BindOnce([](int error) { NOTREACHED(); }));
-  DCHECK_NE(rv, ERR_IO_PENDING);
-  if (rv != OK)
-    return base::WeakPtr<SpdySession>();
-
-  // Check if we have a session through a domain alias.
-  for (const auto& address : request->GetAddressResults().value().endpoints()) {
-    auto range = aliases_.equal_range(address);
-    for (auto alias_it = range.first; alias_it != range.second; ++alias_it) {
-      // We found an alias.
-      const SpdySessionKey& alias_key = alias_it->second;
-
-      // We can reuse this session only if the proxy and privacy
-      // settings match.
-      if (!(alias_key.proxy_server() == key.proxy_server()) ||
-          !(alias_key.privacy_mode() == key.privacy_mode()) ||
-          !(alias_key.is_proxy_session() == key.is_proxy_session())) {
-        continue;
-      }
-
-      auto available_session_it = LookupAvailableSessionByKey(alias_key);
-      if (available_session_it == available_sessions_.end()) {
-        NOTREACHED();  // It shouldn't be in the aliases table if we can't get
-                       // it!
-        continue;
-      }
-
-      // Make copy of WeakPtr as call to UnmapKey() will delete original.
-      const base::WeakPtr<SpdySession> available_session =
-          available_session_it->second;
-      DCHECK(base::ContainsKey(sessions_, available_session.get()));
-
-      if (is_websocket && !available_session->support_websocket())
-        continue;
-
-      // Need to verify that the server is authenticated to serve traffic for
-      // |host_port_proxy_pair| too.
-      if (!available_session->VerifyDomainAuthentication(
-              key.host_port_pair().host())) {
-        UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 0, 2);
-        continue;
-      }
-
-      bool adding_pooled_alias = true;
-
-      // If socket tags differ, see if session's socket tag can be changed.
-      if (alias_key.socket_tag() != key.socket_tag()) {
-        SpdySessionKey old_key = available_session->spdy_session_key();
-        SpdySessionKey new_key(old_key.host_port_pair(), old_key.proxy_server(),
-                               old_key.privacy_mode(),
-                               old_key.is_proxy_session(), key.socket_tag());
-
-        // If there is already a session with |new_key|, skip this one.
-        // It will be found in |aliases_| in a future iteration.
-        if (available_sessions_.find(new_key) != available_sessions_.end())
-          continue;
-
-        if (!available_session->ChangeSocketTag(key.socket_tag()))
-          continue;
-
-        DCHECK(available_session->spdy_session_key() == new_key);
-
-        // This isn't a pooled alias, it's the actual session.
-        adding_pooled_alias = false;
-
-        // Remap main session key.
-        UnmapKey(old_key);
-        MapKeyToAvailableSession(new_key, available_session);
-
-        // Remap alias. From this point on |alias_it| is invalid, so no more
-        // iterations of the loop should be allowed.
-        aliases_.insert(AliasMap::value_type(alias_it->first, new_key));
-        aliases_.erase(alias_it);
-
-        // Remap pooled session keys.
-        const auto& aliases = available_session->pooled_aliases();
-        for (auto it = aliases.begin(); it != aliases.end();) {
-          // Ignore aliases this loop is inserting.
-          if (it->socket_tag() == key.socket_tag()) {
-            ++it;
-            continue;
-          }
-          UnmapKey(*it);
-          SpdySessionKey new_pool_alias_key = SpdySessionKey(
-              it->host_port_pair(), it->proxy_server(), it->privacy_mode(),
-              it->is_proxy_session(), key.socket_tag());
-          MapKeyToAvailableSession(new_pool_alias_key, available_session);
-          auto old_it = it;
-          ++it;
-          available_session->RemovePooledAlias(*old_it);
-          available_session->AddPooledAlias(new_pool_alias_key);
-        }
-      }
-
-      UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2);
-      UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
-                                FOUND_EXISTING_FROM_IP_POOL,
-                                SPDY_SESSION_GET_MAX);
-      net_log.AddEvent(
-          NetLogEventType::
-              HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
-          available_session->net_log().source().ToEventParametersCallback());
-      if (adding_pooled_alias) {
-        // Add this session to the map so that we can find it next time.
-        MapKeyToAvailableSession(key, available_session);
-        available_session->AddPooledAlias(key);
-      }
-      base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(&SpdySessionPool::UpdatePendingRequests,
-                                    weak_ptr_factory_.GetWeakPtr(), key));
-      return available_session;
-    }
+  if (enable_ip_based_pooling) {
+    UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING_FROM_IP_POOL,
+                              SPDY_SESSION_GET_MAX);
+    net_log.AddEvent(
+        NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
+        it->second->net_log().source().ToEventParametersCallback());
+    return it->second;
   }
 
   return base::WeakPtr<SpdySession>();
diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc
index 289fc42..a2808fb 100644
--- a/net/spdy/spdy_session_pool_unittest.cc
+++ b/net/spdy/spdy_session_pool_unittest.cc
@@ -84,6 +84,88 @@
   std::vector<std::unique_ptr<SSLSocketDataProvider>> ssl_data_vector_;
 };
 
+class SpdySessionRequestDelegate
+    : public SpdySessionPool::SpdySessionRequest::Delegate {
+ public:
+  SpdySessionRequestDelegate() = default;
+  ~SpdySessionRequestDelegate() override = default;
+
+  void OnSpdySessionAvailable(
+      base::WeakPtr<SpdySession> spdy_session) override {
+    EXPECT_FALSE(callback_invoked_);
+    callback_invoked_ = true;
+    spdy_session_ = spdy_session;
+  }
+
+  bool callback_invoked() const { return callback_invoked_; }
+
+  SpdySession* spdy_session() { return spdy_session_.get(); }
+
+ private:
+  bool callback_invoked_ = false;
+  base::WeakPtr<SpdySession> spdy_session_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdySessionRequestDelegate);
+};
+
+// Attempts to set up an alias for |key| using an already existing session in
+// |pool|. To do this, simulates a host resolution that returns
+// |ip_address_list|.
+bool TryCreateAliasedSpdySession(SpdySessionPool* pool,
+                                 const SpdySessionKey& key,
+                                 const std::string& ip_address_list,
+                                 bool enable_ip_based_pooling = true,
+                                 bool is_websocket = false) {
+  // The requested session must not already exist.
+  EXPECT_FALSE(pool->FindAvailableSession(key, enable_ip_based_pooling,
+                                          is_websocket, NetLogWithSource()));
+
+  // Create a request for the session. There should be no matching session
+  // (aliased or otherwise) yet. A pending request is necessary for the session
+  // to create an alias on host resolution completion.
+  std::unique_ptr<SpdySessionPool::SpdySessionRequest> request;
+  bool is_blocking_request_for_session = false;
+  SpdySessionRequestDelegate request_delegate;
+  EXPECT_FALSE(pool->RequestSession(
+      key, enable_ip_based_pooling, is_websocket, NetLogWithSource(),
+      /* on_blocking_request_destroyed_callback = */ base::RepeatingClosure(),
+      &request_delegate, &request, &is_blocking_request_for_session));
+  EXPECT_TRUE(request);
+  EXPECT_TRUE(is_blocking_request_for_session);
+
+  AddressList address_list;
+  EXPECT_THAT(
+      ParseAddressList(ip_address_list, /* canonical_name = */ std::string(),
+                       &address_list),
+      IsOk());
+  address_list = AddressList::CopyWithPort(address_list, 443);
+
+  // Simulate a host resolution completing.
+  OnHostResolutionCallbackResult result =
+      pool->OnHostResolutionComplete(key, is_websocket, address_list);
+
+  // Spin the message loop and see if it creates an H2 session.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(request_delegate.callback_invoked(),
+            result == OnHostResolutionCallbackResult::kMayBeDeletedAsync);
+  EXPECT_EQ(request_delegate.callback_invoked(),
+            request_delegate.spdy_session() != nullptr);
+  request.reset();
+
+  // Calling RequestSession again should return request_delegate.spdy_session()
+  // (i.e. the newly created session, if a session was created, or nullptr, if
+  // one was not.)
+  EXPECT_EQ(request_delegate.spdy_session(),
+            pool->RequestSession(key, enable_ip_based_pooling, is_websocket,
+                                 NetLogWithSource(),
+                                 /* on_blocking_request_destroyed_callback = */
+                                 base::RepeatingClosure(), &request_delegate,
+                                 &request, &is_blocking_request_for_session)
+                .get());
+
+  return request_delegate.spdy_session() != nullptr;
+}
+
 // A delegate that opens a new session when it is closed.
 class SessionOpeningDelegate : public SpdyStream::Delegate {
  public:
@@ -340,7 +422,7 @@
 // sessions are closed with SpdySessionPool::CloseIdleSessions().
 void SpdySessionPoolTest::RunIPPoolingTest(
     SpdyPoolCloseSessionsType close_sessions_type) {
-  const int kTestPort = 80;
+  const int kTestPort = 443;
   struct TestHosts {
     std::string url;
     std::string name;
@@ -355,18 +437,10 @@
        "192.168.0.4,192.168.0.3"},
   };
 
-  session_deps_.host_resolver->set_synchronous_mode(true);
   for (size_t i = 0; i < base::size(test_hosts); i++) {
     session_deps_.host_resolver->rules()->AddIPLiteralRule(
         test_hosts[i].name, test_hosts[i].iplist, std::string());
 
-    // This test requires that the HostResolver cache be populated.  Normal
-    // code would have done this already, but we do it manually.
-    int rv = session_deps_.host_resolver->LoadIntoCache(
-        HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
-    EXPECT_THAT(rv, IsOk());
-
-    // Setup a SpdySessionKey.
     test_hosts[i].key =
         SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort),
                        ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
@@ -394,10 +468,12 @@
   base::RunLoop().RunUntilIdle();
 
   // The third host has no overlap with the first, so it can't pool IPs.
-  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
+  EXPECT_FALSE(TryCreateAliasedSpdySession(
+      spdy_session_pool_, test_hosts[2].key, test_hosts[2].iplist));
 
   // The second host overlaps with the first, and should IP pool.
-  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
+  EXPECT_TRUE(TryCreateAliasedSpdySession(spdy_session_pool_, test_hosts[1].key,
+                                          test_hosts[1].iplist));
 
   // However, if IP pooling is disabled, FindAvailableSession() should not find
   // |session| for the second host.
@@ -407,16 +483,19 @@
           /* is_websocket = */ false, NetLogWithSource());
   EXPECT_FALSE(session1);
 
-  // Verify that the second host, through a proxy, won't share the IP.
+  // Verify that the second host, through a proxy, won't share the IP, even if
+  // the IP list matches.
   SpdySessionKey proxy_key(
       test_hosts[1].key.host_port_pair(),
       ProxyServer::FromPacString("HTTP http://proxy.foo.com/"),
       PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kFalse,
       SocketTag());
-  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, proxy_key));
+  EXPECT_FALSE(TryCreateAliasedSpdySession(spdy_session_pool_, proxy_key,
+                                           test_hosts[1].iplist));
 
-  // Overlap between 2 and 3 does is not transitive to 1.
-  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
+  // Overlap between 2 and 3 is not transitive to 1.
+  EXPECT_FALSE(TryCreateAliasedSpdySession(
+      spdy_session_pool_, test_hosts[2].key, test_hosts[2].iplist));
 
   // Create a new session to host 2.
   StaticSocketDataProvider data2(reads, base::span<MockWrite>());
@@ -447,10 +526,6 @@
   pool_peer.RemoveAliases(test_hosts[1].key);
   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
 
-  // Expire the host cache
-  session_deps_.host_resolver->GetHostCache()->clear();
-  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
-
   // Cleanup the sessions.
   switch (close_sessions_type) {
     case SPDY_POOL_CLOSE_SESSIONS_MANUALLY:
@@ -516,10 +591,16 @@
   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[0].key));
   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
+  EXPECT_FALSE(TryCreateAliasedSpdySession(
+      spdy_session_pool_, test_hosts[0].key, test_hosts[0].iplist));
+  EXPECT_FALSE(TryCreateAliasedSpdySession(
+      spdy_session_pool_, test_hosts[1].key, test_hosts[1].iplist));
+  EXPECT_FALSE(TryCreateAliasedSpdySession(
+      spdy_session_pool_, test_hosts[2].key, test_hosts[2].iplist));
 }
 
 void SpdySessionPoolTest::RunIPPoolingDisabledTest(SSLSocketDataProvider* ssl) {
-  const int kTestPort = 80;
+  const int kTestPort = 443;
   struct TestHosts {
     std::string name;
     std::string iplist;
@@ -534,12 +615,6 @@
     session_deps_.host_resolver->rules()->AddIPLiteralRule(
         test_hosts[i].name, test_hosts[i].iplist, std::string());
 
-    // This test requires that the HostResolver cache be populated.  Normal
-    // code would have done this already, but we do it manually.
-    int rv = session_deps_.host_resolver->LoadIntoCache(
-        HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
-    EXPECT_THAT(rv, IsOk());
-
     // Setup a SpdySessionKey
     test_hosts[i].key =
         SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort),
@@ -560,8 +635,9 @@
       http_session_.get(), test_hosts[0].key, NetLogWithSource());
   EXPECT_TRUE(
       HasSpdySession(http_session_->spdy_session_pool(), test_hosts[0].key));
-  EXPECT_FALSE(
-      HasSpdySession(http_session_->spdy_session_pool(), test_hosts[1].key));
+  EXPECT_FALSE(TryCreateAliasedSpdySession(
+      spdy_session_pool_, test_hosts[1].key, test_hosts[1].iplist,
+      /* enable_ip_based_pooling = */ false));
 
   http_session_->spdy_session_pool()->CloseAllSessions();
 }
@@ -596,10 +672,6 @@
     session_deps_.host_resolver->rules()->AddIPLiteralRule(
         test_hosts[i].name, test_hosts[i].iplist, std::string());
 
-    int rv = session_deps_.host_resolver->LoadIntoCache(
-        HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
-    EXPECT_THAT(rv, IsOk());
-
     test_hosts[i].key =
         SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort),
                        ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
@@ -620,9 +692,13 @@
   base::WeakPtr<SpdySession> session0 = CreateSpdySession(
       http_session_.get(), test_hosts[0].key, NetLogWithSource());
 
-  // A request to the second host should pool to the existing connection.
+  // The second host should pool to the existing connection.
   BoundTestNetLog net_log;
   base::HistogramTester histogram_tester;
+  EXPECT_TRUE(TryCreateAliasedSpdySession(spdy_session_pool_, test_hosts[1].key,
+                                          test_hosts[1].iplist));
+  histogram_tester.ExpectTotalCount("Net.SpdySessionGet", 1);
+
   base::WeakPtr<SpdySession> session1 =
       spdy_session_pool_->FindAvailableSession(
           test_hosts[1].key, /* enable_ip_based_pooling = */ true,
@@ -630,30 +706,19 @@
   EXPECT_EQ(session0.get(), session1.get());
 
   ASSERT_EQ(1u, net_log.GetSize());
-  histogram_tester.ExpectTotalCount("Net.SpdySessionGet", 1);
-
-  // A request to the second host should still pool to the existing connection.
-  session1 = spdy_session_pool_->FindAvailableSession(
-      test_hosts[1].key, /* enable_ip_based_pooling = */ true,
-      /* is_websocket = */ false, net_log.bound());
-  EXPECT_EQ(session0.get(), session1.get());
-
-  ASSERT_EQ(2u, net_log.GetSize());
   histogram_tester.ExpectTotalCount("Net.SpdySessionGet", 2);
 
-  // Both FindAvailableSession() calls should log netlog events
-  // indicating IP pooling.
+  // FindAvailableSession() should have logged a netlog event indicating IP
+  // pooling.
   TestNetLogEntry::List entry_list;
   net_log.GetEntries(&entry_list);
   EXPECT_EQ(
       NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
       entry_list[0].type);
-  EXPECT_EQ(
-      NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
-      entry_list[1].type);
 
-  // Both FindAvailableSession() calls should log histogram entries
-  // indicating IP pooling.
+  // Both FindAvailableSession() calls (including one from
+  // TryCreateAliasedSpdySession) should log histogram entries indicating IP
+  // pooling.
   histogram_tester.ExpectUniqueSample("Net.SpdySessionGet", 2, 2);
 }
 
@@ -674,10 +739,6 @@
     session_deps_.host_resolver->rules()->AddIPLiteralRule(
         test_hosts[i].name, test_hosts[i].iplist, std::string());
 
-    int rv = session_deps_.host_resolver->LoadIntoCache(
-        HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
-    EXPECT_THAT(rv, IsOk());
-
     test_hosts[i].key =
         SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort),
                        ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
@@ -704,7 +765,9 @@
   base::WeakPtr<SpdySession> session0 = CreateSpdySession(
       http_session_.get(), test_hosts[0].key, NetLogWithSource());
 
-  // A request to the second host should pool to the existing connection.
+  // |test_hosts[1]| should pool to the existing connection.
+  EXPECT_TRUE(TryCreateAliasedSpdySession(spdy_session_pool_, test_hosts[1].key,
+                                          test_hosts[1].iplist));
   base::WeakPtr<SpdySession> session1 =
       spdy_session_pool_->FindAvailableSession(
           test_hosts[1].key, /* enable_ip_based_pooling = */ true,
@@ -1034,7 +1097,7 @@
   spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED);
 }
 
-TEST_F(SpdySessionPoolTest, FindAvailableSessionForWebSocket) {
+TEST_F(SpdySessionPoolTest, IPConnectionPoolingWithWebSockets) {
   // Define two hosts with identical IP address.
   const int kTestPort = 443;
   struct TestHosts {
@@ -1051,10 +1114,6 @@
     session_deps_.host_resolver->rules()->AddIPLiteralRule(
         test_hosts[i].name, test_hosts[i].iplist, std::string());
 
-    int rv = session_deps_.host_resolver->LoadIntoCache(
-        HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
-    EXPECT_THAT(rv, IsOk());
-
     test_hosts[i].key =
         SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort),
                        ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
@@ -1093,16 +1152,16 @@
   // SpdySession does not support Websocket before SETTINGS frame is read.
   EXPECT_FALSE(session->support_websocket());
   BoundTestNetLog net_log;
-  // FindAvailableSession should not find |session| for either SpdySessionKeys
-  // if |is_websocket| argument is set.
-  base::WeakPtr<SpdySession> result = spdy_session_pool_->FindAvailableSession(
-      test_hosts[0].key, /* enable_ip_based_pooling = */ true,
-      /* is_websocket = */ true, net_log.bound());
-  EXPECT_FALSE(result.get());
-  result = spdy_session_pool_->FindAvailableSession(
-      test_hosts[1].key, /* enable_ip_based_pooling = */ true,
-      /* is_websocket = */ true, net_log.bound());
-  EXPECT_FALSE(result.get());
+  // TryCreateAliasedSpdySession should not find |session| for either
+  // SpdySessionKeys if |is_websocket| argument is set.
+  EXPECT_FALSE(TryCreateAliasedSpdySession(
+      spdy_session_pool_, test_hosts[0].key, test_hosts[0].iplist,
+      /* enable_ip_based_pooling = */ true,
+      /* is_websocket = */ true));
+  EXPECT_FALSE(TryCreateAliasedSpdySession(
+      spdy_session_pool_, test_hosts[1].key, test_hosts[1].iplist,
+      /* enable_ip_based_pooling = */ true,
+      /* is_websocket = */ true));
 
   // Start request that triggers reading the SETTINGS frame.
   const GURL url(kDefaultUrl);
@@ -1119,6 +1178,18 @@
   // Now SpdySession has read the SETTINGS frame and thus supports Websocket.
   EXPECT_TRUE(session->support_websocket());
 
+  // FindAvailableSession() on the first host should now find the existing
+  // session with websockets enabled, and TryCreateAliasedSpdySession() should
+  // now set up aliases for |session| for the second one.
+  base::WeakPtr<SpdySession> result = spdy_session_pool_->FindAvailableSession(
+      test_hosts[0].key, /* enable_ip_based_pooling = */ true,
+      /* is_websocket = */ true, net_log.bound());
+  EXPECT_EQ(session.get(), result.get());
+  EXPECT_TRUE(TryCreateAliasedSpdySession(spdy_session_pool_, test_hosts[1].key,
+                                          test_hosts[1].iplist,
+                                          /* enable_ip_based_pooling = */ true,
+                                          /* is_websocket = */ true));
+
   // FindAvailableSession() should return |session| for either SpdySessionKeys
   // when IP based pooling is enabled.
   result = spdy_session_pool_->FindAvailableSession(
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 52f03b5..314491a2 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -97,6 +97,22 @@
                                   const HashValueVector& hashes));
 };
 
+// SpdySessionRequest::Delegate implementation that does nothing. The test it's
+// used in need to create a session request to trigger the creation of a session
+// alias, but doesn't care about when or if OnSpdySessionAvailable() is invoked.
+class SpdySessionRequestDelegate
+    : public SpdySessionPool::SpdySessionRequest::Delegate {
+ public:
+  SpdySessionRequestDelegate() = default;
+  ~SpdySessionRequestDelegate() override = default;
+
+  void OnSpdySessionAvailable(
+      base::WeakPtr<SpdySession> spdy_session) override {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SpdySessionRequestDelegate);
+};
+
 }  // namespace
 
 class SpdySessionTest : public PlatformTest, public WithScopedTaskEnvironment {
@@ -3571,14 +3587,8 @@
 
   AddSSLSocketData();
 
-  session_deps_.host_resolver->set_synchronous_mode(true);
   session_deps_.host_resolver->rules()->AddIPLiteralRule(
       "www.example.org", "192.168.0.2", std::string());
-  session_deps_.host_resolver->rules()->AddIPLiteralRule(
-      "mail.example.org", "192.168.0.2", std::string());
-  // Not strictly needed.
-  session_deps_.host_resolver->rules()->AddIPLiteralRule("3.com", "192.168.0.3",
-                                                         std::string());
 
   CreateNetworkSession();
 
@@ -3597,17 +3607,28 @@
   SpdySessionKey key2(HostPortPair("mail.example.org", 80),
                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
                       SpdySessionKey::IsProxySession::kFalse, SocketTag());
-  // Pre-populate the DNS cache, since a cached entry is required in order to
-  // create the alias.
-  int rv = session_deps_.host_resolver->LoadIntoCache(key2.host_port_pair(),
-                                                      base::nullopt);
-  EXPECT_THAT(rv, IsOk());
+  std::unique_ptr<SpdySessionPool::SpdySessionRequest> request;
+  bool is_blocking_request_for_session = false;
+  SpdySessionRequestDelegate request_delegate;
+  EXPECT_FALSE(spdy_session_pool_->RequestSession(
+      key2, /* enable_ip_based_pooling = */ true,
+      /* is_websocket = */ false, NetLogWithSource(),
+      /* on_blocking_request_destroyed_callback = */ base::RepeatingClosure(),
+      &request_delegate, &request, &is_blocking_request_for_session));
+  EXPECT_TRUE(request);
+
+  // Simulate DNS resolution completing, which should set up an alias.
+  EXPECT_EQ(OnHostResolutionCallbackResult::kMayBeDeletedAsync,
+            spdy_session_pool_->OnHostResolutionComplete(
+                key2, /* is_websocket = */ false,
+                AddressList(IPEndPoint(IPAddress(192, 168, 0, 2), 80))));
 
   // Get a session for |key2|, which should return the session created earlier.
   base::WeakPtr<SpdySession> session2 =
       spdy_session_pool_->FindAvailableSession(
           key2, /* enable_ip_based_pooling = */ true,
           /* is_websocket = */ false, NetLogWithSource());
+  EXPECT_TRUE(session2);
   ASSERT_EQ(session1.get(), session2.get());
   EXPECT_FALSE(pool->IsStalled());
 
diff --git a/net/tools/quic/quic_simple_client_bin.cc b/net/tools/quic/quic_simple_client_bin.cc
index 1abf5c3e..7faa33ac 100644
--- a/net/tools/quic/quic_simple_client_bin.cc
+++ b/net/tools/quic/quic_simple_client_bin.cc
@@ -275,7 +275,7 @@
   if (!quic_version_string.empty()) {
     if (quic_version_string[0] == 'T') {
       // ParseQuicVersionString checks quic_supports_tls_handshake.
-      SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
+      SetQuicFlag(FLAGS_quic_supports_tls_handshake, true);
     }
     quic::ParsedQuicVersion parsed_quic_version =
         quic::ParseQuicVersionString(quic_version_string);
diff --git a/remoting/webapp/build-html.py b/remoting/webapp/build-html.py
index 8973b6f..1578925 100755
--- a/remoting/webapp/build-html.py
+++ b/remoting/webapp/build-html.py
@@ -164,7 +164,7 @@
 
   # Create the output directory if it does not exist.
   out_directory = os.path.dirname(out_file)
-  if out_directory is not '' and not os.path.exists(out_directory):
+  if out_directory and not os.path.exists(out_directory):
     os.makedirs(out_directory)
 
   # Generate the main HTML file from the templates.
diff --git a/services/audio/stream_factory.cc b/services/audio/stream_factory.cc
index 0d66c9f..ae717272 100644
--- a/services/audio/stream_factory.cc
+++ b/services/audio/stream_factory.cc
@@ -222,13 +222,30 @@
   CHECK_EQ(magic_bytes_, 0x600DC0DEu);
   DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
   DCHECK(muter);
-  SetStateForCrashing("destroying muter");
 
-  const auto it = std::find_if(muters_.begin(), muters_.end(),
-                               base::MatchesUniquePtr(muter));
-  DCHECK(it != muters_.end());
-  muters_.erase(it);
-  SetStateForCrashing("destroyed muter");
+  // Output streams have a task posting before destruction (see the OnError
+  // function in output_stream.cc). To ensure that stream destruction and
+  // unmuting is done in the intended order (the order in which the messeges are
+  // received by the service), we post a task for destroying the muter as well.
+  // Otherwise, a "destroy all streams, then destroy the muter" sequence may
+  // result in a brief blip of audio.
+  auto do_destroy = [](base::WeakPtr<StreamFactory> weak_this,
+                       LocalMuter* muter) {
+    if (weak_this) {
+      weak_this->SetStateForCrashing("destroying muter");
+
+      const auto it =
+          std::find_if(weak_this->muters_.begin(), weak_this->muters_.end(),
+                       base::MatchesUniquePtr(muter));
+      DCHECK(it != weak_this->muters_.end());
+      weak_this->muters_.erase(it);
+      weak_this->SetStateForCrashing("destroyed muter");
+    }
+  };
+
+  base::SequencedTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(do_destroy, weak_ptr_factory_.GetWeakPtr(), muter));
 }
 
 void StreamFactory::DestroyLoopbackStream(LoopbackStream* stream) {
diff --git a/services/audio/stream_factory.h b/services/audio/stream_factory.h
index 2b88f5d..1097dce 100644
--- a/services/audio/stream_factory.h
+++ b/services/audio/stream_factory.h
@@ -13,6 +13,7 @@
 #include "base/containers/flat_set.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "media/mojo/interfaces/audio_logging.mojom.h"
 #include "media/mojo/interfaces/audio_output_stream.mojom.h"
@@ -120,6 +121,8 @@
   // TODO(crbug.com/888478): Remove this after diagnosis.
   volatile uint32_t magic_bytes_;
 
+  base::WeakPtrFactory<StreamFactory> weak_ptr_factory_{this};
+
   DISALLOW_COPY_AND_ASSIGN(StreamFactory);
 };
 
diff --git a/testing/BUILD.gn b/testing/BUILD.gn
index a5ccdd3..ff188ba 100644
--- a/testing/BUILD.gn
+++ b/testing/BUILD.gn
@@ -27,6 +27,24 @@
   ]
 }
 
+if (is_mac || is_win) {
+  group("rendering_representative_perf_tests") {
+    testonly = true
+    deps = [
+      "//tools/perf/chrome_telemetry_build:telemetry_chrome_test",
+    ]
+    data = [
+      "//build/android/pylib",
+      "//chrome/test/data/perf",
+      "//testing/scripts",
+      "//testing/test_env.py",
+      "//testing/xvfb.py",
+      "//third_party/catapult",
+      "//tools",
+    ]
+  }
+}
+
 group("run_perf_test") {
   data = [
     "//testing/scripts/common.py",
diff --git a/testing/buildbot/chromium.chrome.json b/testing/buildbot/chromium.chrome.json
index c1a9788f..253f7e6 100644
--- a/testing/buildbot/chromium.chrome.json
+++ b/testing/buildbot/chromium.chrome.json
@@ -884,6 +884,28 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "experiment_percentage": 100,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04",
+              "pool": "chrome.tests"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "experiment_percentage": 100,
         "merge": {
           "args": [],
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 99f3df62..8c0f7b2 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -1460,6 +1460,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -2932,6 +2952,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index 2395cc47..c33fe87 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -703,6 +703,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -2172,6 +2192,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10-15063"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -3644,6 +3685,27 @@
         "test": "installer_util_unittests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10-15063"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -10320,6 +10382,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -11770,6 +11852,27 @@
       },
       {
         "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -13232,6 +13335,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -14549,6 +14672,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -15868,6 +16011,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -17202,6 +17365,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18537,6 +18720,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -19613,6 +19816,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -20654,6 +20872,22 @@
       },
       {
         "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -21536,6 +21770,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -22559,6 +22808,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -23555,6 +23819,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -24551,6 +24830,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25855,6 +26149,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10-15063"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27415,6 +27730,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10-15063"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28975,6 +29311,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10-15063"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -30227,6 +30584,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -31223,6 +31595,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -32219,6 +32606,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -33215,6 +33617,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -34211,6 +34628,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -35362,6 +35794,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -36764,6 +37216,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Windows-10"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 24855f1..20375d7 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -450,6 +450,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -2836,6 +2851,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -9490,6 +9520,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "isolate_coverage_data": true,
         "merge": {
           "args": [],
@@ -11052,6 +11103,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "isolate_coverage_data": true,
         "merge": {
           "args": [],
@@ -12505,6 +12577,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -14095,6 +14187,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "isolate_coverage_data": true,
         "merge": {
           "args": [],
@@ -18184,6 +18297,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -19821,6 +19954,28 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.14.5"
+            }
+          ],
+          "expiration": 21600
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 6db1736..2d97575 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -14845,6 +14845,21 @@
         }
       },
       {
+        "args": [],
+        "experiment_percentage": 100,
+        "isolate_name": "rendering_representative_perf_tests",
+        "name": "rendering_representative_perf_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12.6"
+            }
+          ]
+        }
+      },
+      {
         "args": [
           "screenshot_sync",
           "--show-stdout",
@@ -16223,6 +16238,23 @@
         }
       },
       {
+        "args": [],
+        "experiment_percentage": 100,
+        "isolate_name": "rendering_representative_perf_tests",
+        "name": "rendering_representative_perf_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac-10.13.6",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
         "args": [
           "screenshot_sync",
           "--show-stdout",
@@ -22821,6 +22853,22 @@
         }
       },
       {
+        "args": [],
+        "experiment_percentage": 100,
+        "isolate_name": "rendering_representative_perf_tests",
+        "name": "rendering_representative_perf_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
         "args": [
           "screenshot_sync",
           "--show-stdout",
@@ -24717,6 +24765,31 @@
         }
       },
       {
+        "args": [],
+        "experiment_percentage": 100,
+        "isolate_name": "rendering_representative_perf_tests",
+        "name": "rendering_representative_perf_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "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",
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 3387438..229944d 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -2773,6 +2773,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -4353,6 +4373,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5892,6 +5932,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -7394,6 +7454,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "isolate_coverage_data": true,
         "merge": {
           "args": [],
@@ -9104,6 +9185,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 0142c6ad..fa6ac04f 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -707,6 +707,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.10"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -2129,6 +2150,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.11"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -3551,6 +3593,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12.6"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5010,6 +5073,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6463,6 +6547,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -7910,6 +8015,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 7fba115..f13bd1e 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -3479,6 +3479,27 @@
       },
       {
         "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -5022,6 +5043,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6526,6 +6567,27 @@
       },
       {
         "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -8294,6 +8356,28 @@
       },
       {
         "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -10023,6 +10107,28 @@
       },
       {
         "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -11612,6 +11718,27 @@
       },
       {
         "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -12880,6 +13007,22 @@
       },
       {
         "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -14222,6 +14365,26 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Windows-10-15063"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index 1abe0fcb..105028b 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -562,6 +562,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -2004,6 +2019,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10-15063"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -3698,6 +3734,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10-15063"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5215,6 +5272,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6356,6 +6428,21 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn
index 2981e77..b3f46ff 100644
--- a/testing/buildbot/filters/BUILD.gn
+++ b/testing/buildbot/filters/BUILD.gn
@@ -79,6 +79,14 @@
   ]
 }
 
+source_set("interactive_ui_tests_filters") {
+  testonly = true
+
+  data = [
+    "//testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter",
+  ]
+}
+
 source_set("webview_cts_tests_filters") {
   testonly = true
 
diff --git a/testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter b/testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter
new file mode 100644
index 0000000..1730bd14
--- /dev/null
+++ b/testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter
@@ -0,0 +1,11 @@
+# https://crbug.com/924031, https://crbug.com/925517: Need to test all Web UI
+# pages that have been migrated to use HTML imports polyfill with the Blink
+# HTML imports feature turned off, before the Blink team disables the feature by
+# default.
+
+PrintPreviewButtonStripInteractiveTest.*
+PrintPreviewDestinationDialogInteractiveTest.*
+PrintPreviewNumberSettingsSectionInteractiveTest.BlurResetsEmptyInput
+PrintPreviewPagesSettingsTest.*
+PrintPreviewPrintHeaderInteractiveTest.FocusPrintOnReady
+PrintPreviewScalingSettingsInteractiveTest.InputAutoFocus
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 52a39d2..431e0ec 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -2207,6 +2207,17 @@
     "label": "//content/test/fuzzer:renderer_tree_fuzzer",
     "type": "fuzzer",
   },
+  "rendering_representative_perf_tests": {
+    "args": [
+      "../../tools/perf/run_benchmark",
+      "--benchmarks=rendering.desktop",
+      "--output-format=csv",
+      "--browser=release",
+    ],
+    "label": "//testing:rendering_representative_perf_tests",
+    "script": "//testing/scripts/run_rendering_benchmark_with_gated_performance.py",
+    "type": "script",
+  },
   "residual_echo_detector_fuzzer": {
     "label": "//third_party/webrtc/test/fuzzers:residual_echo_detector_fuzzer",
     "type": "fuzzer",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index c9e7331..96228d0 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -3937,6 +3937,13 @@
         ],
         'test': 'browser_tests',
       },
+      'webui_html_imports_polyfill_interactive_ui_tests': {
+        'args': [
+          '--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0',
+          '--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter',
+        ],
+        'test': 'interactive_ui_tests',
+      },
     },
 
     'non_linux_chromium_gtests': {
@@ -4045,6 +4052,15 @@
       },
     },
 
+    'rendering_representative_perf_tests_isolated_scripts': {
+      'rendering_representative_perf_tests': {
+        'isolate_name': 'rendering_representative_perf_tests',
+        'args': [],
+        'swarming': {},
+        'experiment_percentage': 100,
+      }
+    },
+
     'site_isolation_android_fyi_gtests': {
       'site_per_process_components_browsertests': {
         'args': [
@@ -4525,6 +4541,11 @@
 
     # BEGIN composition test suites used by the GPU bots
 
+    'gpu_angle_and_representative_perf_fyi_isolated_scripts': [
+      'gpu_angle_perf_isolated_scripts',
+      'rendering_representative_perf_tests_isolated_scripts',
+    ],
+
     'gpu_angle_deqp_android_gtests': [
       'gpu_angle_deqp_egl_gles_gtests',
       'gpu_angle_deqp_gles_gtests',
@@ -4571,6 +4592,13 @@
       'gpu_angle_deqp_gles31_gl_gtests',
     ],
 
+    'gpu_angle_fyi_win_optional_and_representative_perf_isolated_scripts': [
+      'gpu_angle_perf_isolated_scripts',
+      'gpu_command_buffer_perf_passthrough_isolated_scripts',
+      'gpu_command_buffer_perf_validating_isolated_scripts',
+      'rendering_representative_perf_tests_isolated_scripts',
+    ],
+
     'gpu_angle_fyi_win_optional_isolated_scripts': [
       'gpu_angle_perf_isolated_scripts',
       'gpu_command_buffer_perf_passthrough_isolated_scripts',
diff --git a/testing/buildbot/tryserver.chromium.linux.json b/testing/buildbot/tryserver.chromium.linux.json
index d0cc871..354605b 100644
--- a/testing/buildbot/tryserver.chromium.linux.json
+++ b/testing/buildbot/tryserver.chromium.linux.json
@@ -725,6 +725,27 @@
         "test": "interactive_ui_tests"
       },
       {
+        "args": [
+          "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webui_html_imports_polyfill_interactive_ui_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
         "isolate_coverage_data": true,
         "merge": {
           "args": [],
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 5c6a151..44f9c8d 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -2897,6 +2897,7 @@
         'test_suites': {
           'gtest_tests': 'gpu_fyi_mac_release_gtests',
           'gpu_telemetry_tests': 'gpu_fyi_mac_release_telemetry_tests',
+          'isolated_scripts': 'rendering_representative_perf_tests_isolated_scripts',
         },
       },
       'Mac FYI Retina Debug (AMD)': {
@@ -2930,6 +2931,7 @@
         'test_suites': {
           'gtest_tests': 'gpu_fyi_mac_release_gtests',
           'gpu_telemetry_tests': 'gpu_fyi_mac_release_telemetry_tests',
+          'isolated_scripts': 'rendering_representative_perf_tests_isolated_scripts',
         },
       },
       'Mac FYI Retina Release (NVIDIA)': {
@@ -3152,7 +3154,7 @@
         ],
         'test_suites': {
           'gtest_tests': 'gpu_fyi_win_gtests',
-          'isolated_scripts': 'gpu_angle_perf_isolated_scripts',
+          'isolated_scripts': 'gpu_angle_and_representative_perf_fyi_isolated_scripts',
           'gpu_telemetry_tests': 'gpu_fyi_win_intel_release_telemetry_tests',
         },
       },
@@ -3178,7 +3180,7 @@
         ],
         'test_suites': {
           'gtest_tests': 'gpu_fyi_win_gtests',
-          'isolated_scripts': 'gpu_angle_fyi_win_optional_isolated_scripts',
+          'isolated_scripts': 'gpu_angle_fyi_win_optional_and_representative_perf_isolated_scripts',
           'gpu_telemetry_tests': 'gpu_fyi_win_release_telemetry_tests',
         },
         # We keep this value enabled to provide minimal regression testing.
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index 066c2463..ff0eade 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -12,6 +12,7 @@
 import("//tools/grit/repack.gni")
 
 if (is_android) {
+  import("//build/config/android/config.gni")
   import("//build/config/android/rules.gni")
 }
 
@@ -597,6 +598,9 @@
     "grit/blink_resources.h",
     "blink_resources.pak",
   ]
+  if (is_android) {
+    defines = [ "notouch_build=$notouch_build" ]
+  }
   html_min_css = "$blink_core_output_dir/html.css"
   grit_flags = [
     "-E",
diff --git a/third_party/blink/public/blink_resources.grd b/third_party/blink/public/blink_resources.grd
index e447c255..375c78cf 100644
--- a/third_party/blink/public/blink_resources.grd
+++ b/third_party/blink/public/blink_resources.grd
@@ -18,6 +18,9 @@
       <if expr="is_macosx">
         <include name="IDR_UASTYLE_THEME_MAC_CSS" file="../renderer/core/html/resources/mac.css" type="BINDATA" compress="gzip"/>
       </if>
+      <if expr="notouch_build">
+        <include name="IDR_UASTYLE_THEME_TOUCHLESS_CSS" file="../renderer/core/css/touchless.css" type="BINDATA" compress="gzip"/>
+      </if>
       <include name="IDR_UASTYLE_THEME_INPUT_MULTIPLE_FIELDS_CSS" file="../renderer/core/html/resources/input_multiple_fields.css" type="BINDATA" compress="gzip"/>
       <include name="IDR_UASTYLE_THEME_WIN_CSS" file="../renderer/core/html/resources/win.css" type="BINDATA" compress="gzip"/>
       <include name="IDR_UASTYLE_THEME_WIN_QUIRKS_CSS" file="../renderer/core/html/resources/win_quirks.css" type="BINDATA" compress="gzip"/>
diff --git a/third_party/blink/public/mojom/portal/portal.mojom b/third_party/blink/public/mojom/portal/portal.mojom
index 07c20cce..35772e1 100644
--- a/third_party/blink/public/mojom/portal/portal.mojom
+++ b/third_party/blink/public/mojom/portal/portal.mojom
@@ -33,7 +33,7 @@
 interface PortalClient {
   // Forwards message sent from the portal's guest to the portal's host
   // HTMLPortalElement.
-  ForwardMessageFromGuest(string message,
+  ForwardMessageFromGuest(TransferableMessage message,
                           url.mojom.Origin source_origin,
                           url.mojom.Origin? target_origin);
 };
@@ -45,5 +45,5 @@
   // the portal's host HTMLPortalElement. |targetOrigin| indicates which origin
   // the message can be delivered to, and if null, it indicates that the message
   // can be delivered to any origin.
-  PostMessageToHost(string message, url.mojom.Origin? target_origin);
+  PostMessageToHost(TransferableMessage message, url.mojom.Origin? target_origin);
 };
diff --git a/third_party/blink/public/mojom/renderer_preferences.mojom b/third_party/blink/public/mojom/renderer_preferences.mojom
index e15295c..8fcd4502 100644
--- a/third_party/blink/public/mojom/renderer_preferences.mojom
+++ b/third_party/blink/public/mojom/renderer_preferences.mojom
@@ -40,11 +40,8 @@
   // positions for glyphs.  Currently only used by Linux.
   bool use_subpixel_positioning = false;
 
+  // The color of the focus ring. Currently only used on Linux.
   uint32 focus_ring_color = 0xFFE59700;
-  [EnableIf=is_android]
-  float minimum_stroke_width_for_focus_ring = 1.0;
-  [EnableIf=is_android]
-  bool is_focus_ring_outset = false;
 
   // The colors used in selection text. Currently only used on Linux and Ash.
   uint32 active_selection_bg_color = 0xFF1E90FF;
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
index 7c8f6d44..4570662 100644
--- a/third_party/blink/public/platform/web_runtime_features.h
+++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -137,7 +137,6 @@
   BLINK_PLATFORM_EXPORT static void EnableOverlayScrollbars(bool);
   BLINK_PLATFORM_EXPORT static void EnableOverscrollCustomization(bool);
   BLINK_PLATFORM_EXPORT static void EnableOutOfBlinkCors(bool);
-  BLINK_PLATFORM_EXPORT static void EnablePageLifecycle(bool);
   BLINK_PLATFORM_EXPORT static void EnablePagePopup(bool);
   BLINK_PLATFORM_EXPORT static void EnablePassiveDocumentEventListeners(bool);
   BLINK_PLATFORM_EXPORT static void EnablePassiveDocumentWheelEventListeners(
diff --git a/third_party/blink/public/web/web_render_theme.h b/third_party/blink/public/web/web_render_theme.h
index 210239f0..7a1e0af 100644
--- a/third_party/blink/public/web/web_render_theme.h
+++ b/third_party/blink/public/web/web_render_theme.h
@@ -42,10 +42,6 @@
 
 BLINK_EXPORT void SetFocusRingColor(SkColor);
 
-BLINK_EXPORT void SetMinimumStrokeWidthForFocusRing(float);
-
-BLINK_EXPORT void SetIsFocusRingOutset(bool);
-
 }  // namespace blink
 
 #endif
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc b/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc
index 7b3cc33..96fea5a 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc
@@ -5,8 +5,10 @@
 #include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/frame.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/window_post_message_options.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/core/messaging/post_message_options.h"
 
@@ -100,4 +102,28 @@
   return nullptr;
 }
 
+// static
+scoped_refptr<const SecurityOrigin> PostMessageHelper::GetTargetOrigin(
+    const WindowPostMessageOptions* options,
+    const Document& source_document,
+    ExceptionState& exception_state) {
+  const String& target_origin = options->targetOrigin();
+  if (target_origin == "/")
+    return source_document.GetSecurityOrigin();
+  if (target_origin == "*")
+    return nullptr;
+  scoped_refptr<const SecurityOrigin> target =
+      SecurityOrigin::CreateFromString(target_origin);
+  // It doesn't make sense target a postMessage at an opaque origin
+  // because there's no way to represent an opaque origin in a string.
+  if (target->IsOpaque()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+                                      "Invalid target origin '" +
+                                          target_origin +
+                                          "' in a call to 'postMessage'.");
+    return nullptr;
+  }
+  return target;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h b/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h
index 9c521c9..72ee655 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h
@@ -13,12 +13,15 @@
 
 namespace blink {
 
+class Document;
 class ExecutionContext;
 class ExceptionState;
 class PostMessageOptions;
 class ScriptValue;
+class SecurityOrigin;
 class SerializedScriptValue;
 class Transferables;
+class WindowPostMessageOptions;
 
 class CORE_EXPORT PostMessageHelper {
   STATIC_ONLY(PostMessageHelper);
@@ -43,6 +46,13 @@
   static mojom::blink::UserActivationSnapshotPtr CreateUserActivationSnapshot(
       ExecutionContext*,
       const PostMessageOptions*);
+
+  // Extracts target origin from |options|. Throws SyntaxError, if the origin
+  // provided is an invalid URL.
+  static scoped_refptr<const SecurityOrigin> GetTargetOrigin(
+      const WindowPostMessageOptions* options,
+      const Document& document,
+      ExceptionState& state);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 0d19ca0..12ae4df 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -32,6 +32,9 @@
   if (blink_animation_use_time_delta) {
     defines += [ "BLINK_ANIMATION_USE_TIME_DELTA" ]
   }
+  if (is_android && notouch_build) {
+    defines += [ "ENABLE_TOUCHLESS_UASTYLE_THEME" ]
+  }
 }
 
 config("core_include_dirs") {
diff --git a/third_party/blink/renderer/core/css/css_default_style_sheets.cc b/third_party/blink/renderer/core/css/css_default_style_sheets.cc
index 175651e5..f99a469 100644
--- a/third_party/blink/renderer/core/css/css_default_style_sheets.cc
+++ b/third_party/blink/renderer/core/css/css_default_style_sheets.cc
@@ -121,6 +121,10 @@
   default_style_->AddRulesFromSheet(DefaultStyleSheet(), ScreenEval());
   default_print_style_->AddRulesFromSheet(DefaultStyleSheet(), PrintEval());
   default_quirks_style_->AddRulesFromSheet(QuirksStyleSheet(), ScreenEval());
+
+#if defined(ENABLE_TOUCHLESS_UASTYLE_THEME)
+  EnsureDefaultStyleSheetForTouchless();
+#endif
 }
 
 RuleSet* CSSDefaultStyleSheets::DefaultViewSourceStyle() {
@@ -214,6 +218,20 @@
                                            ScreenEval());
 }
 
+void CSSDefaultStyleSheets::EnsureDefaultStyleSheetForTouchless() {
+  if (touchless_style_sheet_)
+    return;
+
+  String touchless_rules = GetDataResourceAsASCIIString("touchless.css");
+  if (touchless_rules.IsEmpty())
+    return;
+
+  touchless_style_sheet_ = ParseUASheet(touchless_rules);
+  default_style_->AddRulesFromSheet(touchless_style_sheet_.Get(), ScreenEval());
+  default_quirks_style_->AddRulesFromSheet(touchless_style_sheet_.Get(),
+                                           ScreenEval());
+}
+
 void CSSDefaultStyleSheets::Trace(blink::Visitor* visitor) {
   visitor->Trace(default_style_);
   visitor->Trace(default_quirks_style_);
@@ -228,6 +246,7 @@
   visitor->Trace(mathml_style_sheet_);
   visitor->Trace(media_controls_style_sheet_);
   visitor->Trace(fullscreen_style_sheet_);
+  visitor->Trace(touchless_style_sheet_);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_default_style_sheets.h b/third_party/blink/renderer/core/css/css_default_style_sheets.h
index bc67b93..bcb7fc8 100644
--- a/third_party/blink/renderer/core/css/css_default_style_sheets.h
+++ b/third_party/blink/renderer/core/css/css_default_style_sheets.h
@@ -46,6 +46,7 @@
 
   bool EnsureDefaultStyleSheetsForElement(const Element&);
   void EnsureDefaultStyleSheetForFullscreen();
+  void EnsureDefaultStyleSheetForTouchless();
 
   RuleSet* DefaultStyle() { return default_style_.Get(); }
   RuleSet* DefaultQuirksStyle() { return default_quirks_style_.Get(); }
@@ -104,6 +105,7 @@
   Member<StyleSheetContents> mathml_style_sheet_;
   Member<StyleSheetContents> media_controls_style_sheet_;
   Member<StyleSheetContents> fullscreen_style_sheet_;
+  Member<StyleSheetContents> touchless_style_sheet_;
 
   std::unique_ptr<UAStyleSheetLoader> media_controls_style_sheet_loader_;
   DISALLOW_COPY_AND_ASSIGN(CSSDefaultStyleSheets);
diff --git a/third_party/blink/renderer/core/css/touchless.css b/third_party/blink/renderer/core/css/touchless.css
new file mode 100644
index 0000000..c298cc3
--- /dev/null
+++ b/third_party/blink/renderer/core/css/touchless.css
@@ -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. */
+
+video:focus {
+    outline: none !important;
+    box-shadow: none !important
+}
+
+input[type = text],
+input[type = email],
+input[type = date],
+input[type = datetime],
+input[type = datetime-local],
+input[type = month],
+input[type = number],
+input[type = password],
+input[type = search],
+input[type = time],
+video:-internal-spatial-navigation-interest {
+    outline-offset: -4px
+}
+
+:-internal-spatial-navigation-interest {
+    outline: auto 4px #185ABC !important;
+    box-shadow: none !important
+}
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index ebbb2b09..98a564e9 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -3720,7 +3720,6 @@
 }
 
 void Document::DispatchFreezeEvent() {
-  DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled());
   const TimeTicks freeze_event_start = CurrentTimeTicks();
   SetFreezingInProgress(true);
   DispatchEvent(*Event::Create(event_type_names::kFreeze));
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl
index fdef9500..378f053 100644
--- a/third_party/blink/renderer/core/dom/document.idl
+++ b/third_party/blink/renderer/core/dom/document.idl
@@ -178,7 +178,7 @@
     // https://w3c.github.io/page-visibility/#extensions-to-the-document-interface
     readonly attribute boolean hidden;
     readonly attribute VisibilityState visibilityState;
-    [RuntimeEnabled=PageLifecycle] readonly attribute boolean wasDiscarded;
+    readonly attribute boolean wasDiscarded;
 
     // CORS and RFC1918
     // https://wicg.github.io/cors-rfc1918/#feature-detect
@@ -201,8 +201,8 @@
     attribute EventHandler onbeforecopy;
     attribute EventHandler onbeforecut;
     attribute EventHandler onbeforepaste;
-    [RuntimeEnabled=PageLifecycle] attribute EventHandler onfreeze;
-    [RuntimeEnabled=PageLifecycle] attribute EventHandler onresume;
+    attribute EventHandler onfreeze;
+    attribute EventHandler onresume;
     attribute EventHandler onsearch;
     [RuntimeEnabled=ExperimentalContentSecurityPolicyFeatures] attribute EventHandler onsecuritypolicyviolation;
     attribute EventHandler onvisibilitychange;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 9d4c1485..0714ac0 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2101,6 +2101,9 @@
     // AttachLayoutTree again. We don't clear pseudo elements on
     // DetachLayoutTree() if we intend to attach again to avoid recreating the
     // pseudo elements.
+    //
+    // TODO(futhark): This block can be removed when LazyReattachIfAttached is
+    // removed.
     ElementRareData* rare_data = GetElementRareData();
     rare_data->ClearPseudoElements();
   }
diff --git a/third_party/blink/renderer/core/dom/node_test.cc b/third_party/blink/renderer/core/dom/node_test.cc
index 9e99d5e..9e2a8294 100644
--- a/third_party/blink/renderer/core/dom/node_test.cc
+++ b/third_party/blink/renderer/core/dom/node_test.cc
@@ -36,7 +36,7 @@
 class NodeTest : public EditingTestBase {
  protected:
   LayoutObject* ReattachLayoutTreeForNode(Node& node) {
-    node.LazyReattachIfAttached();
+    node.SetForceReattachLayoutTree();
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
     GetDocument().GetStyleEngine().RecalcStyle({});
     Node::AttachContext context;
@@ -326,6 +326,7 @@
 }
 
 TEST_F(NodeTest, LazyReattachCommentAndPI) {
+  // TODO(futhark): Remove this test when LazyReattachIfAttached is removed.
   SetBodyContent("<!-- -->");
   HTMLElement* body = GetDocument().body();
   ProcessingInstruction* pi =
diff --git a/third_party/blink/renderer/core/dom/range_test.cc b/third_party/blink/renderer/core/dom/range_test.cc
index 35ade003..2308287d 100644
--- a/third_party/blink/renderer/core/dom/range_test.cc
+++ b/third_party/blink/renderer/core/dom/range_test.cc
@@ -278,7 +278,7 @@
 }
 
 TEST_F(RangeTest, ToPosition) {
-  Node& textarea = *HTMLTextAreaElement::Create(GetDocument());
+  auto& textarea = *MakeGarbageCollected<HTMLTextAreaElement>(GetDocument());
   Range& range = *Range::Create(GetDocument());
   const Position position = Position(&textarea, 0);
   range.setStart(position, ASSERT_NO_EXCEPTION);
diff --git a/third_party/blink/renderer/core/dom/v0_insertion_point.cc b/third_party/blink/renderer/core/dom/v0_insertion_point.cc
index dae1722..ace284e 100644
--- a/third_party/blink/renderer/core/dom/v0_insertion_point.cc
+++ b/third_party/blink/renderer/core/dom/v0_insertion_point.cc
@@ -67,7 +67,7 @@
       for (; j < distributed_nodes.size() &&
              distributed_nodes_.at(i) != distributed_nodes.at(j);
            ++j)
-        distributed_nodes.at(j)->LazyReattachIfAttached();
+        distributed_nodes.at(j)->FlatTreeParentChanged();
       if (j == distributed_nodes.size())
         break;
     } else if (distributed_nodes_.size() > distributed_nodes.size()) {
@@ -76,13 +76,13 @@
       for (; i < distributed_nodes_.size() &&
              distributed_nodes_.at(i) != distributed_nodes.at(j);
            ++i)
-        distributed_nodes_.at(i)->LazyReattachIfAttached();
+        distributed_nodes_.at(i)->FlatTreeParentChanged();
       if (i == distributed_nodes_.size())
         break;
     } else if (distributed_nodes_.at(i) != distributed_nodes.at(j)) {
       // If both distributions are the same length reattach both old and new.
-      distributed_nodes_.at(i)->LazyReattachIfAttached();
-      distributed_nodes.at(j)->LazyReattachIfAttached();
+      distributed_nodes_.at(i)->FlatTreeParentChanged();
+      distributed_nodes.at(j)->FlatTreeParentChanged();
     }
   }
 
@@ -90,10 +90,10 @@
   // nodes.
 
   for (; i < distributed_nodes_.size(); ++i)
-    distributed_nodes_.at(i)->LazyReattachIfAttached();
+    distributed_nodes_.at(i)->FlatTreeParentChanged();
 
   for (; j < distributed_nodes.size(); ++j)
-    distributed_nodes.at(j)->LazyReattachIfAttached();
+    distributed_nodes.at(j)->FlatTreeParentChanged();
 
   distributed_nodes_.Swap(distributed_nodes);
   // Deallocate a Vector and a HashMap explicitly so that
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
index 791523d..df4254f 100644
--- a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
+++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
@@ -56,11 +56,11 @@
   if (position.IsNull())
     return TextOffset();
 
-  if (!position.ComputeContainerNode()->IsTextNode())
+  auto* text_node = DynamicTo<Text>(position.ComputeContainerNode());
+  if (!text_node)
     return TextOffset();
 
-  return TextOffset(ToText(position.ComputeContainerNode()),
-                    position.OffsetInContainerNode());
+  return TextOffset(text_node, position.OffsetInContainerNode());
 }
 
 template <typename EditingStrategy>
@@ -496,7 +496,7 @@
     return;
   switch (node.getNodeType()) {
     case Node::kTextNode: {
-      Text& text = ToText(node);
+      auto& text = To<Text>(node);
       if (text.parentElement() && IsHTMLTextAreaElement(text.parentElement())) {
         accumulator_->AppendText(text);
         break;
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer_test.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer_test.cc
index 5513569..9179f50 100644
--- a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer_test.cc
+++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer_test.cc
@@ -224,7 +224,7 @@
       "id='one'>11</span></span></p>\n";
   SetBodyContent(body_content);
   Element* one = GetDocument().getElementById("one");
-  Text* text = ToText(one->firstChild());
+  auto* text = To<Text>(one->firstChild());
   Position start_dom(text, 0);
   Position end_dom(text, 2);
   const std::string& serialized_dom = SerializePart<EditingStrategy>(
@@ -237,7 +237,7 @@
   SetBodyContent(body_content);
   SetShadowContent(shadow_content, "host");
   one = GetDocument().getElementById("one");
-  text = ToText(one->firstChild());
+  text = To<Text>(one->firstChild());
   PositionInFlatTree start_ict(text, 0);
   PositionInFlatTree end_ict(text, 2);
   const std::string& serialized_ict = SerializePart<EditingInFlatTreeStrategy>(
@@ -253,8 +253,8 @@
   SetBodyContent(body_content);
   Element* one = GetDocument().getElementById("one");
   Element* two = GetDocument().getElementById("two");
-  Position start_dom(ToText(one->firstChild()), 0);
-  Position end_dom(ToText(two->firstChild()), 2);
+  Position start_dom(To<Text>(one->firstChild()), 0);
+  Position end_dom(To<Text>(two->firstChild()), 2);
   const std::string& serialized_dom = SerializePart<EditingStrategy>(
       start_dom, end_dom, kAnnotateForInterchange);
 
@@ -268,8 +268,8 @@
   SetShadowContent(shadow_content2, "host2");
   one = GetDocument().getElementById("one");
   two = GetDocument().getElementById("two");
-  PositionInFlatTree start_ict(ToText(one->firstChild()), 0);
-  PositionInFlatTree end_ict(ToText(two->firstChild()), 2);
+  PositionInFlatTree start_ict(To<Text>(one->firstChild()), 0);
+  PositionInFlatTree end_ict(To<Text>(two->firstChild()), 2);
   const std::string& serialized_ict = SerializePart<EditingInFlatTreeStrategy>(
       start_ict, end_ict, kAnnotateForInterchange);
 
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
index 3daafd0..e8c6f47 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
+++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
@@ -413,10 +413,11 @@
   GetFrame().GetDocument()->UpdateStyleAndLayoutTreeForNode(&element);
 
   for (Node& node : NodeTraversal::InclusiveDescendantsOf(element)) {
+    auto* text_node = DynamicTo<Text>(node);
     if ((elements_type == ElementsType::kAll || !HasEditableStyle(node)) &&
-        node.IsTextNode()) {
+        text_node) {
       GetFrame().GetDocument()->Markers().RemoveMarkersForNode(
-          ToText(node), DocumentMarker::MarkerTypes::Misspelling());
+          *text_node, DocumentMarker::MarkerTypes::Misspelling());
     }
   }
 }
@@ -566,13 +567,14 @@
                                      .ComputeVisibleSelectionInDOMTree()
                                      .Start()
                                      .AnchorNode());
-  if (!node || !node->IsTextNode())
+  auto* text_node = DynamicTo<Text>(node);
+  if (!text_node)
     return false;
 
   unsigned start_offset = static_cast<unsigned>(from);
   unsigned end_offset = static_cast<unsigned>(from + length);
   DocumentMarkerVector markers =
-      GetFrame().GetDocument()->Markers().MarkersFor(ToText(*node));
+      GetFrame().GetDocument()->Markers().MarkersFor(*text_node);
   for (wtf_size_t i = 0; i < markers.size(); ++i) {
     DocumentMarker* marker = markers[i];
     if (marker->StartOffset() <= start_offset &&
diff --git a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
index 48dbff5..befa220 100644
--- a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
+++ b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
@@ -74,18 +74,16 @@
 
 EphemeralRangeInFlatTree ComputeRangeSurroundingCaret(
     const PositionInFlatTree& caret_position) {
-  const Node* const position_node = caret_position.ComputeContainerNode();
-  const bool is_text_node = position_node->IsTextNode();
   const unsigned position_offset_in_node =
       caret_position.ComputeOffsetInContainerNode();
-
+  auto* text_node = DynamicTo<Text>(caret_position.ComputeContainerNode());
   // If we're in the interior of a text node, we can avoid calling
   // PreviousPositionOf/NextPositionOf for better efficiency.
-  if (is_text_node && position_offset_in_node != 0 &&
-      position_offset_in_node != ToText(position_node)->length()) {
+  if (text_node && position_offset_in_node != 0 &&
+      position_offset_in_node != text_node->length()) {
     return EphemeralRangeInFlatTree(
-        PositionInFlatTree(position_node, position_offset_in_node - 1),
-        PositionInFlatTree(position_node, position_offset_in_node + 1));
+        PositionInFlatTree(text_node, position_offset_in_node - 1),
+        PositionInFlatTree(text_node, position_offset_in_node + 1));
   }
 
   const PositionInFlatTree& previous_position =
@@ -551,18 +549,18 @@
       range.EndPosition().ComputeOffsetInContainerNode();
 
   for (const Node& node : range.Nodes()) {
-    if (!node.IsTextNode())
+    auto* text_node = DynamicTo<Text>(node);
+    if (!text_node)
       continue;
 
     const unsigned start_offset =
         node == range_start_container ? range_start_offset : 0;
-    const unsigned end_offset = node == range_end_container
-                                    ? range_end_offset
-                                    : ToText(node).length();
+    const unsigned end_offset =
+        node == range_end_container ? range_end_offset : text_node->length();
 
     const DocumentMarker* const found_marker =
         GetFrame().GetDocument()->Markers().FirstMarkerIntersectingOffsetRange(
-            ToText(node), start_offset, end_offset, types);
+            *text_node, start_offset, end_offset, types);
     if (found_marker)
       return std::make_pair(&node, found_marker);
   }
diff --git a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc
index d0b3dbd..65ca6e7 100644
--- a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc
+++ b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc
@@ -84,7 +84,7 @@
       "word1 word2 word3 word4"
       "</div>");
   Element* div = GetDocument().QuerySelector("div");
-  Text* text = ToText(div->firstChild());
+  auto* text = To<Text>(div->firstChild());
 
   // Add marker on "word1". This marker should *not* be cleared by the
   // replace operation.
@@ -195,7 +195,7 @@
       "mispelled"
       "</div>");
   Element* div = GetDocument().QuerySelector("div");
-  Text* text = ToText(div->firstChild());
+  auto* text = To<Text>(div->firstChild());
 
   // Add marker on "mispelled". This marker should be cleared by the replace
   // operation.
@@ -472,7 +472,7 @@
       "hello"
       "</div>");
   Element* div = GetDocument().QuerySelector("div");
-  Text* text = ToText(div->firstChild());
+  auto* text = To<Text>(div->firstChild());
 
   // Set suggestion marker with empty suggestion list.
   GetDocument().Markers().AddSuggestionMarker(
@@ -521,7 +521,7 @@
       "hello"
       "</div>");
   Element* div = GetDocument().QuerySelector("div");
-  Text* text = ToText(div->firstChild());
+  auto* text = To<Text>(div->firstChild());
 
   // Set suggestion marker with two suggestions.
   GetDocument().Markers().AddSuggestionMarker(
diff --git a/third_party/blink/renderer/core/editing/text_offset_mapping.cc b/third_party/blink/renderer/core/editing/text_offset_mapping.cc
index bbe1d84..a49900ca 100644
--- a/third_party/blink/renderer/core/editing/text_offset_mapping.cc
+++ b/third_party/blink/renderer/core/editing/text_offset_mapping.cc
@@ -379,12 +379,13 @@
   }
   const Node& first_node = *first_->NonPseudoNode();
   const Node& last_node = *last_->NonPseudoNode();
+  auto* first_text_node = DynamicTo<Text>(first_node);
+  auto* last_text_node = DynamicTo<Text>(last_node);
   return EphemeralRangeInFlatTree(
-      first_node.IsTextNode() ? PositionInFlatTree(first_node, 0)
-                              : PositionInFlatTree::BeforeNode(first_node),
-      last_node.IsTextNode()
-          ? PositionInFlatTree(last_node, ToText(last_node).length())
-          : PositionInFlatTree::AfterNode(last_node));
+      first_text_node ? PositionInFlatTree(first_node, 0)
+                      : PositionInFlatTree::BeforeNode(first_node),
+      last_text_node ? PositionInFlatTree(last_node, last_text_node->length())
+                     : PositionInFlatTree::AfterNode(last_node));
 }
 
 PositionInFlatTree
diff --git a/third_party/blink/renderer/core/editing/visible_units.cc b/third_party/blink/renderer/core/editing/visible_units.cc
index 84e6a01..3ded39a 100644
--- a/third_party/blink/renderer/core/editing/visible_units.cc
+++ b/third_party/blink/renderer/core/editing/visible_units.cc
@@ -459,7 +459,8 @@
           (o->IsLayoutInline() && IsEmptyInline(LineLayoutItem(o)) &&
            // TODO(crbug.com/771398): Find alternative ways to check whether an
            // empty LayoutInline is rendered, without checking InlineBox.
-           BoundingBoxLogicalHeight(o, ToLayoutInline(o)->LinesBoundingBox())))
+           BoundingBoxLogicalHeight(
+               o, ToLayoutInline(o)->PhysicalLinesBoundingBox())))
         return true;
     }
   }
@@ -995,11 +996,10 @@
       MostForwardCaretPosition(visible_position.DeepEquivalent());
   if (!pos.IsOffsetInAnchor())
     return 0;
-  Node* container_node = pos.ComputeContainerNode();
-  if (!container_node || !container_node->IsTextNode())
+  auto* text_node = DynamicTo<Text>(pos.ComputeContainerNode());
+  if (!text_node)
     return 0;
   unsigned offset = static_cast<unsigned>(pos.OffsetInContainerNode());
-  Text* text_node = ToText(container_node);
   unsigned length = text_node->length();
   if (offset >= length)
     return 0;
diff --git a/third_party/blink/renderer/core/editing/visible_units_line.cc b/third_party/blink/renderer/core/editing/visible_units_line.cc
index 4cae02b..840e70d 100644
--- a/third_party/blink/renderer/core/editing/visible_units_line.cc
+++ b/third_party/blink/renderer/core/editing/visible_units_line.cc
@@ -179,10 +179,10 @@
     return PositionWithAffinityTemplate<Strategy>();
 
   const Node* const start_node = start_box->GetLineLayoutItem().NonPseudoNode();
-  DCHECK(start_node);
+  auto* text_start_node = DynamicTo<Text>(start_node);
   return PositionWithAffinityTemplate<Strategy>(
-      start_node->IsTextNode()
-          ? PositionTemplate<Strategy>(ToText(start_node),
+      text_start_node
+          ? PositionTemplate<Strategy>(text_start_node,
                                        ToInlineTextBox(start_box)->Start())
           : PositionTemplate<Strategy>::BeforeNode(*start_node));
 }
@@ -456,13 +456,15 @@
         PositionTemplate<Strategy>::BeforeNode(*end_node),
         TextAffinity::kUpstreamIfPossible);
   }
-  if (end_box->IsInlineTextBox() && end_node->IsTextNode()) {
+
+  auto* end_text_node = DynamicTo<Text>(end_node);
+  if (end_box->IsInlineTextBox() && end_text_node) {
     const InlineTextBox* end_text_box = ToInlineTextBox(end_box);
     int end_offset = end_text_box->Start();
     if (!end_text_box->IsLineBreak())
       end_offset += end_text_box->Len();
     return PositionWithAffinityTemplate<Strategy>(
-        PositionTemplate<Strategy>(ToText(end_node), end_offset),
+        PositionTemplate<Strategy>(end_text_node, end_offset),
         TextAffinity::kUpstreamIfPossible);
   }
   return PositionWithAffinityTemplate<Strategy>(
diff --git a/third_party/blink/renderer/core/editing/visible_units_paragraph.cc b/third_party/blink/renderer/core/editing/visible_units_paragraph.cc
index de2358b..2c8f3a3a 100644
--- a/third_party/blink/renderer/core/editing/visible_units_paragraph.cc
+++ b/third_party/blink/renderer/core/editing/visible_units_paragraph.cc
@@ -104,7 +104,6 @@
     if (layout_object->IsText() &&
         ToLayoutText(previous_node_iterator->GetLayoutObject())
             ->ResolvedTextLength()) {
-      SECURITY_DCHECK(previous_node_iterator->IsTextNode());
       if (style.PreserveNewline()) {
         LayoutText* text =
             ToLayoutText(previous_node_iterator->GetLayoutObject());
@@ -113,7 +112,7 @@
           index = max(0, candidate_offset);
         while (--index >= 0) {
           if ((*text)[index] == '\n') {
-            return PositionTemplate<Strategy>(ToText(previous_node_iterator),
+            return PositionTemplate<Strategy>(To<Text>(previous_node_iterator),
                                               index + 1);
           }
         }
@@ -207,14 +206,13 @@
     // can't accept the caret.
     if (layout_object->IsText() &&
         ToLayoutText(layout_object)->ResolvedTextLength()) {
-      SECURITY_DCHECK(next_node_iterator->IsTextNode());
       LayoutText* const text = ToLayoutText(layout_object);
       if (style.PreserveNewline()) {
         const int length = ToLayoutText(layout_object)->TextLength();
         for (int i = (next_node_iterator == start_node ? candidate_offset : 0);
              i < length; ++i) {
           if ((*text)[i] == '\n') {
-            return PositionTemplate<Strategy>(ToText(next_node_iterator),
+            return PositionTemplate<Strategy>(To<Text>(next_node_iterator),
                                               i + text->TextStartOffset());
           }
         }
diff --git a/third_party/blink/renderer/core/editing/visible_units_test.cc b/third_party/blink/renderer/core/editing/visible_units_test.cc
index 85cc6c02..6e002c7 100644
--- a/third_party/blink/renderer/core/editing/visible_units_test.cc
+++ b/third_party/blink/renderer/core/editing/visible_units_test.cc
@@ -420,7 +420,7 @@
   Node* sample = GetDocument().getElementById("sample");
   Node* first_letter = sample->firstChild();
   // Split "abc" into "a" "bc"
-  Text* remaining = ToText(first_letter)->splitText(1, ASSERT_NO_EXCEPTION);
+  auto* remaining = To<Text>(first_letter)->splitText(1, ASSERT_NO_EXCEPTION);
   UpdateAllLifecyclePhasesForTest();
 
   EXPECT_EQ(Position(sample, 0),
diff --git a/third_party/blink/renderer/core/events/message_event.cc b/third_party/blink/renderer/core/events/message_event.cc
index 85b9fda9..bf2ce4c 100644
--- a/third_party/blink/renderer/core/events/message_event.cc
+++ b/third_party/blink/renderer/core/events/message_event.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
 #include "third_party/blink/renderer/core/event_interface_names.h"
 #include "third_party/blink/renderer/core/frame/user_activation.h"
+#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
 
@@ -39,7 +40,8 @@
 
 static inline bool IsValidSource(EventTarget* source) {
   return !source || source->ToLocalDOMWindow() || source->ToMessagePort() ||
-         source->ToServiceWorker() || source->ToPortalHost();
+         source->ToServiceWorker() || source->ToPortalHost() ||
+         ToHTMLPortalElementOrNull(source->ToNode());
 }
 
 MessageEvent::V8GCAwareString::V8GCAwareString(const String& value)
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 92581fe..d19739e3 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -327,7 +327,7 @@
     int node_count = 0;
     for (Node& node : range.Nodes()) {
       const DocumentMarkerVector& markers_in_node =
-          document->Markers().MarkersFor(ToText(node), marker_types);
+          document->Markers().MarkersFor(To<Text>(node), marker_types);
       node_count += std::count_if(
           markers_in_node.begin(), markers_in_node.end(),
           [start_offset, end_offset, &node, &start_container,
diff --git a/third_party/blink/renderer/core/exported/web_render_theme.cc b/third_party/blink/renderer/core/exported/web_render_theme.cc
index dff6608..4213986 100644
--- a/third_party/blink/renderer/core/exported/web_render_theme.cc
+++ b/third_party/blink/renderer/core/exported/web_render_theme.cc
@@ -44,12 +44,4 @@
   LayoutTheme::GetTheme().SetCustomFocusRingColor(color);
 }
 
-void SetMinimumStrokeWidthForFocusRing(float stroke_width) {
-  LayoutTheme::GetTheme().SetMinimumStrokeWidthForFocusRing(stroke_width);
-}
-
-void SetIsFocusRingOutset(bool is_outset) {
-  LayoutTheme::GetTheme().SetIsFocusRingOutset(is_outset);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc
index 514f79e..1c1c5e1 100644
--- a/third_party/blink/renderer/core/frame/dom_window.cc
+++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -424,38 +424,24 @@
 
   Document* source_document = source->document();
 
-  const String& target_origin = options->targetOrigin();
+  // Capture the source of the message.  We need to do this synchronously
+  // in order to capture the source of the message correctly.
+  if (!source_document)
+    return;
 
   // Compute the target origin.  We need to do this synchronously in order
   // to generate the SyntaxError exception correctly.
-  scoped_refptr<const SecurityOrigin> target;
-  if (target_origin == "/") {
-    if (!source_document)
-      return;
-    target = source_document->GetSecurityOrigin();
-  } else if (target_origin != "*") {
-    target = SecurityOrigin::CreateFromString(target_origin);
-    // It doesn't make sense target a postMessage at a unique origin
-    // because there's no way to represent a unique origin in a string.
-    if (target->IsOpaque()) {
-      exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
-                                        "Invalid target origin '" +
-                                            target_origin +
-                                            "' in a call to 'postMessage'.");
-      return;
-    }
-  }
+  scoped_refptr<const SecurityOrigin> target =
+      PostMessageHelper::GetTargetOrigin(options, *source_document,
+                                         exception_state);
+  if (exception_state.HadException())
+    return;
 
   auto channels = MessagePort::DisentanglePorts(GetExecutionContext(), ports,
                                                 exception_state);
   if (exception_state.HadException())
     return;
 
-  // Capture the source of the message.  We need to do this synchronously
-  // in order to capture the source of the message correctly.
-  if (!source_document)
-    return;
-
   const SecurityOrigin* security_origin = source_document->GetSecurityOrigin();
 
   String source_origin = security_origin->ToString();
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 519003fe..0e506d3c 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -108,6 +108,7 @@
 #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/microtask.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/timer.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -1256,7 +1257,7 @@
 
 CustomElementRegistry* LocalDOMWindow::customElements() const {
   if (!custom_elements_ && document_)
-    custom_elements_ = CustomElementRegistry::Create(this);
+    custom_elements_ = MakeGarbageCollected<CustomElementRegistry>(this);
   return custom_elements_;
 }
 
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 24f40cc2..6bc973f1 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -325,26 +325,6 @@
   return Tree().Parent()->IsRemoteFrame();
 }
 
-static bool MustReplaceCurrentItem(LocalFrame* frame) {
-  // Non-user navigation before the page has finished firing onload should not
-  // create a new back/forward item. See https://webkit.org/b/42861 for the
-  // original motivation for this.
-  if (!frame->GetDocument()->LoadEventFinished() &&
-      !LocalFrame::HasTransientUserActivation(frame)) {
-    return true;
-  }
-
-  // Navigation of a subframe during loading of an ancestor frame does not
-  // create a new back/forward item. The definition of "during load" is any time
-  // before all handlers for the load event have been run. See
-  // https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation
-  // for this.
-  Frame* parent_frame = frame->Tree().Parent();
-  auto* parent_local_frame = DynamicTo<LocalFrame>(parent_frame);
-  return parent_local_frame &&
-         !parent_local_frame->Loader().AllAncestorsAreComplete();
-}
-
 void LocalFrame::Navigate(const FrameLoadRequest& request,
                           WebFrameLoadType frame_load_type) {
   if (!navigation_rate_limiter().CanProceed())
@@ -352,8 +332,13 @@
   if (request.ClientRedirect() == ClientRedirectPolicy::kClientRedirect) {
     probe::FrameScheduledNavigation(this, request.GetResourceRequest().Url(),
                                     0.0, request.ClientRedirectReason());
-    if (MustReplaceCurrentItem(this))
+    // Non-user navigation before the page has finished firing onload should not
+    // create a new back/forward item. The spec only explicitly mentions this in
+    // the context of navigating an iframe.
+    if (!GetDocument()->LoadEventFinished() &&
+        !HasTransientUserActivation(this)) {
       frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
+    }
   }
   loader_.StartNavigation(request, frame_load_type);
 
@@ -581,7 +566,6 @@
 }
 
 void LocalFrame::DidFreeze() {
-  DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled());
   if (GetDocument()) {
     auto* document_resource_coordinator =
         GetDocument()->GetResourceCoordinator();
@@ -607,7 +591,6 @@
 }
 
 void LocalFrame::DidResume() {
-  DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled());
   if (GetDocument()) {
     const TimeTicks resume_event_start = CurrentTimeTicks();
     GetDocument()->DispatchEvent(*Event::Create(event_type_names::kResume));
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index bd41cde..305aa99 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2761,10 +2761,12 @@
                            LocalFrameUkmAggregator::kCompositingCommit);
 
   PaintArtifactCompositor::ViewportProperties viewport_properties;
-  const auto& viewport = page->GetVisualViewport();
-  viewport_properties.page_scale = viewport.GetPageScaleNode();
-  viewport_properties.inner_scroll_translation =
-      viewport.GetScrollTranslationNode();
+  if (GetFrame().IsMainFrame()) {
+    const auto& viewport = page->GetVisualViewport();
+    viewport_properties.page_scale = viewport.GetPageScaleNode();
+    viewport_properties.inner_scroll_translation =
+        viewport.GetScrollTranslationNode();
+  }
 
   PaintArtifactCompositor::Settings settings;
   settings.prefer_compositing_to_lcd_text =
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc
index 0b4e5d7..1f218a1 100644
--- a/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -172,12 +172,10 @@
 }
 
 void RemoteFrame::DidFreeze() {
-  DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled());
   // TODO(fmeawad): Add support for remote frames.
 }
 
 void RemoteFrame::DidResume() {
-  DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled());
   // TODO(fmeawad): Add support for remote frames.
 }
 
diff --git a/third_party/blink/renderer/core/frame/sandbox_flags.cc b/third_party/blink/renderer/core/frame/sandbox_flags.cc
index 68cb9a0..86bbc00 100644
--- a/third_party/blink/renderer/core/frame/sandbox_flags.cc
+++ b/third_party/blink/renderer/core/frame/sandbox_flags.cc
@@ -37,11 +37,6 @@
 
 namespace blink {
 
-// An array of pairs of some sandbox flags and their corresponding
-// FeaturePolicies that implement them. Eventually almost all sandbox flags
-// should be converted to feature policies (https://crbug.com/812381).
-using SandboxFlagFeaturePolicyPairs =
-    Vector<std::pair<WebSandboxFlags, mojom::FeaturePolicyFeature>>;
 const SandboxFlagFeaturePolicyPairs& SandboxFlagsWithFeaturePolicies() {
   DEFINE_STATIC_LOCAL(
       SandboxFlagFeaturePolicyPairs, array,
diff --git a/third_party/blink/renderer/core/frame/sandbox_flags.h b/third_party/blink/renderer/core/frame/sandbox_flags.h
index 4f28e55b..df8ef0ed 100644
--- a/third_party/blink/renderer/core/frame/sandbox_flags.h
+++ b/third_party/blink/renderer/core/frame/sandbox_flags.h
@@ -35,6 +35,13 @@
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 
 namespace blink {
+using SandboxFlagFeaturePolicyPairs =
+    Vector<std::pair<WebSandboxFlags, mojom::FeaturePolicyFeature>>;
+
+// Returns a vector of pairs of sandbox flags and the corresponding feature
+// policies. This includes most but not all sandbox flags as some flags have not
+// yet migrated to using feature policies.
+const SandboxFlagFeaturePolicyPairs& SandboxFlagsWithFeaturePolicies();
 
 WebSandboxFlags ParseSandboxPolicy(const SpaceSplitString& policy,
                                    String& invalid_tokens_error_message);
diff --git a/third_party/blink/renderer/core/html/BUILD.gn b/third_party/blink/renderer/core/html/BUILD.gn
index b243ffdd..620b4d7 100644
--- a/third_party/blink/renderer/core/html/BUILD.gn
+++ b/third_party/blink/renderer/core/html/BUILD.gn
@@ -505,6 +505,8 @@
     "portal/html_portal_element.h",
     "portal/portal_host.cc",
     "portal/portal_host.h",
+    "portal/portal_post_message_helper.cc",
+    "portal/portal_post_message_helper.h",
     "rel_list.cc",
     "rel_list.h",
     "shadow/details_marker_control.cc",
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_registry.cc b/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
index 13d7a65..d6fae1d 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
@@ -75,23 +75,17 @@
 
 }  // namespace
 
-CustomElementRegistry* CustomElementRegistry::Create(
-    const LocalDOMWindow* owner) {
-  CustomElementRegistry* registry =
-      MakeGarbageCollected<CustomElementRegistry>(owner);
-  Document* document = owner->document();
-  if (V0CustomElementRegistrationContext* v0 =
-          document ? document->RegistrationContext() : nullptr)
-    registry->Entangle(v0);
-  return registry;
-}
-
 CustomElementRegistry::CustomElementRegistry(const LocalDOMWindow* owner)
     : element_definition_is_running_(false),
       owner_(owner),
       v0_(MakeGarbageCollected<V0RegistrySet>()),
       upgrade_candidates_(MakeGarbageCollected<UpgradeCandidateMap>()),
-      reaction_stack_(&CustomElementReactionStack::Current()) {}
+      reaction_stack_(&CustomElementReactionStack::Current()) {
+  Document* document = owner->document();
+  if (V0CustomElementRegistrationContext* v0 =
+          document ? document->RegistrationContext() : nullptr)
+    Entangle(v0);
+}
 
 void CustomElementRegistry::Trace(Visitor* visitor) {
   visitor->Trace(definitions_);
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_registry.h b/third_party/blink/renderer/core/html/custom/custom_element_registry.h
index 8f3ae3e3..3c959f9 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_registry.h
+++ b/third_party/blink/renderer/core/html/custom/custom_element_registry.h
@@ -34,8 +34,6 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static CustomElementRegistry* Create(const LocalDOMWindow*);
-
   CustomElementRegistry(const LocalDOMWindow*);
   ~CustomElementRegistry() override = default;
 
diff --git a/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc b/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc
index ca126aa0..54603695 100644
--- a/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc
+++ b/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc
@@ -35,15 +35,6 @@
 
 namespace blink {
 
-V0CustomElementMicrotaskResolutionStep*
-V0CustomElementMicrotaskResolutionStep::Create(
-    V0CustomElementRegistrationContext* context,
-    Element* element,
-    const V0CustomElementDescriptor& descriptor) {
-  return MakeGarbageCollected<V0CustomElementMicrotaskResolutionStep>(
-      context, element, descriptor);
-}
-
 V0CustomElementMicrotaskResolutionStep::V0CustomElementMicrotaskResolutionStep(
     V0CustomElementRegistrationContext* context,
     Element* element,
diff --git a/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h b/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h
index 320286e..2d28a2dc 100644
--- a/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h
+++ b/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h
@@ -43,11 +43,6 @@
 class V0CustomElementMicrotaskResolutionStep final
     : public V0CustomElementMicrotaskStep {
  public:
-  static V0CustomElementMicrotaskResolutionStep* Create(
-      V0CustomElementRegistrationContext*,
-      Element*,
-      const V0CustomElementDescriptor&);
-
   V0CustomElementMicrotaskResolutionStep(V0CustomElementRegistrationContext*,
                                          Element*,
                                          const V0CustomElementDescriptor&);
diff --git a/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h b/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h
index 92e29a3..83c4f53 100644
--- a/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h
+++ b/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h
@@ -45,10 +45,6 @@
 class V0CustomElementRegistrationContext final
     : public GarbageCollectedFinalized<V0CustomElementRegistrationContext> {
  public:
-  static V0CustomElementRegistrationContext* Create() {
-    return MakeGarbageCollected<V0CustomElementRegistrationContext>();
-  }
-
   V0CustomElementRegistrationContext();
   ~V0CustomElementRegistrationContext() = default;
   void DocumentWasDetached() { registry_.DocumentWasDetached(); }
diff --git a/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc b/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc
index 0cc3000..7e9edad 100644
--- a/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc
+++ b/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc
@@ -43,6 +43,7 @@
 #include "third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h"
 #include "third_party/blink/renderer/core/html/imports/html_import_child.h"
 #include "third_party/blink/renderer/core/html/imports/html_imports_controller.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 
 namespace blink {
 
@@ -125,9 +126,8 @@
   }
 
   Document& document = element->GetDocument();
-  V0CustomElementMicrotaskResolutionStep* step =
-      V0CustomElementMicrotaskResolutionStep::Create(context, element,
-                                                     descriptor);
+  auto* step = MakeGarbageCollected<V0CustomElementMicrotaskResolutionStep>(
+      context, element, descriptor);
   EnqueueMicrotaskStep(document, step);
 }
 
diff --git a/third_party/blink/renderer/core/html/document_name_collection.h b/third_party/blink/renderer/core/html/document_name_collection.h
index 09463fa..792d702 100644
--- a/third_party/blink/renderer/core/html/document_name_collection.h
+++ b/third_party/blink/renderer/core/html/document_name_collection.h
@@ -12,13 +12,6 @@
 
 class DocumentNameCollection final : public HTMLNameCollection {
  public:
-  static DocumentNameCollection* Create(ContainerNode& document,
-                                        CollectionType type,
-                                        const AtomicString& name) {
-    DCHECK_EQ(type, kDocumentNamedItems);
-    return MakeGarbageCollected<DocumentNameCollection>(document, name);
-  }
-
   DocumentNameCollection(ContainerNode& document, const AtomicString& name);
   DocumentNameCollection(ContainerNode& document,
                          CollectionType type,
diff --git a/third_party/blink/renderer/core/html/forms/base_button_input_type.cc b/third_party/blink/renderer/core/html/forms/base_button_input_type.cc
index b206e0d..07b6187 100644
--- a/third_party/blink/renderer/core/html/forms/base_button_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/base_button_input_type.cc
@@ -62,7 +62,7 @@
 }
 
 void BaseButtonInputType::ValueAttributeChanged() {
-  ToTextOrDie(GetElement().UserAgentShadowRoot()->firstChild())
+  To<Text>(GetElement().UserAgentShadowRoot()->firstChild())
       ->setData(DisplayValue());
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/button_input_type.cc b/third_party/blink/renderer/core/html/forms/button_input_type.cc
index bd17ef8..9003997 100644
--- a/third_party/blink/renderer/core/html/forms/button_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/button_input_type.cc
@@ -35,10 +35,6 @@
 
 namespace blink {
 
-InputType* ButtonInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<ButtonInputType>(element);
-}
-
 void ButtonInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeButton);
 }
diff --git a/third_party/blink/renderer/core/html/forms/button_input_type.h b/third_party/blink/renderer/core/html/forms/button_input_type.h
index b9abffe..d53bdce 100644
--- a/third_party/blink/renderer/core/html/forms/button_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/button_input_type.h
@@ -37,8 +37,6 @@
 
 class ButtonInputType final : public BaseButtonInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   ButtonInputType(HTMLInputElement& element) : BaseButtonInputType(element) {}
 
  private:
diff --git a/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc b/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc
index d5d1c2c..3c929e7 100644
--- a/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc
@@ -40,10 +40,6 @@
 
 namespace blink {
 
-InputType* CheckboxInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<CheckboxInputType>(element);
-}
-
 void CheckboxInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeCheckbox);
 }
diff --git a/third_party/blink/renderer/core/html/forms/checkbox_input_type.h b/third_party/blink/renderer/core/html/forms/checkbox_input_type.h
index ab00d840..afca5bb9 100644
--- a/third_party/blink/renderer/core/html/forms/checkbox_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/checkbox_input_type.h
@@ -37,8 +37,6 @@
 
 class CheckboxInputType final : public BaseCheckableInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   CheckboxInputType(HTMLInputElement& element)
       : BaseCheckableInputType(element) {}
 
diff --git a/third_party/blink/renderer/core/html/forms/color_input_type.cc b/third_party/blink/renderer/core/html/forms/color_input_type.cc
index c7615ac5..c2f6fef 100644
--- a/third_party/blink/renderer/core/html/forms/color_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/color_input_type.cc
@@ -77,10 +77,6 @@
 ColorInputType::ColorInputType(HTMLInputElement& element)
     : InputType(element), KeyboardClickableInputTypeView(element) {}
 
-InputType* ColorInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<ColorInputType>(element);
-}
-
 ColorInputType::~ColorInputType() = default;
 
 void ColorInputType::Trace(Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/html/forms/color_input_type.h b/third_party/blink/renderer/core/html/forms/color_input_type.h
index f755a60e4..19cfe68 100644
--- a/third_party/blink/renderer/core/html/forms/color_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/color_input_type.h
@@ -45,7 +45,6 @@
   USING_GARBAGE_COLLECTED_MIXIN(ColorInputType);
 
  public:
-  static InputType* Create(HTMLInputElement&);
   explicit ColorInputType(HTMLInputElement&);
   ~ColorInputType() override;
   void Trace(Visitor*) override;
diff --git a/third_party/blink/renderer/core/html/forms/date_input_type.cc b/third_party/blink/renderer/core/html/forms/date_input_type.cc
index 0bd61ed..999f2243 100644
--- a/third_party/blink/renderer/core/html/forms/date_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/date_input_type.cc
@@ -48,13 +48,9 @@
 static const int kDateDefaultStepBase = 0;
 static const int kDateStepScaleFactor = 86400000;
 
-inline DateInputType::DateInputType(HTMLInputElement& element)
+DateInputType::DateInputType(HTMLInputElement& element)
     : BaseTemporalInputType(element) {}
 
-InputType* DateInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<DateInputType>(element);
-}
-
 void DateInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeDate);
 }
diff --git a/third_party/blink/renderer/core/html/forms/date_input_type.h b/third_party/blink/renderer/core/html/forms/date_input_type.h
index b5a8e7eb..24bac53 100644
--- a/third_party/blink/renderer/core/html/forms/date_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/date_input_type.h
@@ -37,8 +37,6 @@
 
 class DateInputType final : public BaseTemporalInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   explicit DateInputType(HTMLInputElement&);
 
  private:
diff --git a/third_party/blink/renderer/core/html/forms/date_time_field_element.cc b/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
index c1b93a2..289147f 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
@@ -207,7 +207,7 @@
 }
 
 void DateTimeFieldElement::UpdateVisibleValue(EventBehavior event_behavior) {
-  Text* const text_node = ToText(firstChild());
+  auto* const text_node = To<Text>(firstChild());
   const String new_visible_value = VisibleValue();
   DCHECK_GT(new_visible_value.length(), 0u);
 
diff --git a/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc b/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc
index ddf1980..0f12fd7b 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc
@@ -49,10 +49,6 @@
 static const int kDateTimeLocalDefaultStepBase = 0;
 static const int kDateTimeLocalStepScaleFactor = 1000;
 
-InputType* DateTimeLocalInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<DateTimeLocalInputType>(element);
-}
-
 void DateTimeLocalInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeDateTimeLocal);
 }
diff --git a/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h b/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h
index 8404bdf4b..7dbfce0 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h
@@ -39,8 +39,6 @@
 
 class DateTimeLocalInputType final : public BaseTemporalInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   explicit DateTimeLocalInputType(HTMLInputElement& element)
       : BaseTemporalInputType(element) {}
 
diff --git a/third_party/blink/renderer/core/html/forms/email_input_type.cc b/third_party/blink/renderer/core/html/forms/email_input_type.cc
index dd937e4a47..699cd73 100644
--- a/third_party/blink/renderer/core/html/forms/email_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/email_input_type.cc
@@ -159,10 +159,6 @@
 EmailInputType::EmailInputType(HTMLInputElement& element)
     : BaseTextInputType(element) {}
 
-InputType* EmailInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<EmailInputType>(element);
-}
-
 void EmailInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeEmail);
   bool has_max_length =
diff --git a/third_party/blink/renderer/core/html/forms/email_input_type.h b/third_party/blink/renderer/core/html/forms/email_input_type.h
index 0e37b497..f63fa717 100644
--- a/third_party/blink/renderer/core/html/forms/email_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/email_input_type.h
@@ -37,8 +37,6 @@
 
 class EmailInputType final : public BaseTextInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   explicit EmailInputType(HTMLInputElement&);
 
   // They are public for unit testing.
diff --git a/third_party/blink/renderer/core/html/forms/file_input_type.cc b/third_party/blink/renderer/core/html/forms/file_input_type.cc
index 50f8f66..61c2ceb 100644
--- a/third_party/blink/renderer/core/html/forms/file_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/file_input_type.cc
@@ -67,15 +67,11 @@
 
 }  // namespace
 
-inline FileInputType::FileInputType(HTMLInputElement& element)
+FileInputType::FileInputType(HTMLInputElement& element)
     : InputType(element),
       KeyboardClickableInputTypeView(element),
       file_list_(MakeGarbageCollected<FileList>()) {}
 
-InputType* FileInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<FileInputType>(element);
-}
-
 void FileInputType::Trace(Visitor* visitor) {
   visitor->Trace(file_list_);
   KeyboardClickableInputTypeView::Trace(visitor);
diff --git a/third_party/blink/renderer/core/html/forms/file_input_type.h b/third_party/blink/renderer/core/html/forms/file_input_type.h
index 4af28a5..256a752 100644
--- a/third_party/blink/renderer/core/html/forms/file_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/file_input_type.h
@@ -51,8 +51,6 @@
   USING_GARBAGE_COLLECTED_MIXIN(FileInputType);
 
  public:
-  static InputType* Create(HTMLInputElement&);
-
   FileInputType(HTMLInputElement&);
 
   void Trace(Visitor*) override;
diff --git a/third_party/blink/renderer/core/html/forms/file_input_type_test.cc b/third_party/blink/renderer/core/html/forms/file_input_type_test.cc
index 33f2d2a..613906d 100644
--- a/third_party/blink/renderer/core/html/forms/file_input_type_test.cc
+++ b/third_party/blink/renderer/core/html/forms/file_input_type_test.cc
@@ -15,6 +15,7 @@
 #include "third_party/blink/renderer/core/page/drag_data.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
 #include "third_party/blink/renderer/platform/file_metadata.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/wtf/date_math.h"
 
 namespace blink {
@@ -63,7 +64,7 @@
 TEST(FileInputTypeTest, ignoreDroppedNonNativeFiles) {
   Document* document = Document::CreateForTest();
   auto* input = HTMLInputElement::Create(*document, CreateElementFlags());
-  InputType* file_input = FileInputType::Create(*input);
+  InputType* file_input = MakeGarbageCollected<FileInputType>(*input);
 
   DataObject* native_file_raw_drag_data = DataObject::Create();
   const DragData native_file_drag_data(native_file_raw_drag_data, FloatPoint(),
@@ -95,7 +96,7 @@
 TEST(FileInputTypeTest, setFilesFromPaths) {
   Document* document = Document::CreateForTest();
   auto* input = HTMLInputElement::Create(*document, CreateElementFlags());
-  InputType* file_input = FileInputType::Create(*input);
+  InputType* file_input = MakeGarbageCollected<FileInputType>(*input);
   Vector<String> paths;
   paths.push_back("/native/path");
   paths.push_back("/native/path2");
diff --git a/third_party/blink/renderer/core/html/forms/hidden_input_type.cc b/third_party/blink/renderer/core/html/forms/hidden_input_type.cc
index c2cde6d..773f9cf 100644
--- a/third_party/blink/renderer/core/html/forms/hidden_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/hidden_input_type.cc
@@ -43,10 +43,6 @@
 
 using namespace html_names;
 
-InputType* HiddenInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<HiddenInputType>(element);
-}
-
 void HiddenInputType::CountUsage() {
   UseCounter::Count(GetElement().GetDocument(), WebFeature::kInputTypeHidden);
 }
diff --git a/third_party/blink/renderer/core/html/forms/hidden_input_type.h b/third_party/blink/renderer/core/html/forms/hidden_input_type.h
index eddb2e1..5e211f6 100644
--- a/third_party/blink/renderer/core/html/forms/hidden_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/hidden_input_type.h
@@ -40,8 +40,6 @@
   USING_GARBAGE_COLLECTED_MIXIN(HiddenInputType);
 
  public:
-  static InputType* Create(HTMLInputElement&);
-
   HiddenInputType(HTMLInputElement& element)
       : InputType(element), InputTypeView(element) {}
 
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
index 0289733b0..bc97294 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -80,10 +80,6 @@
   EnsureUserAgentShadowRoot();
 }
 
-HTMLTextAreaElement* HTMLTextAreaElement::Create(Document& document) {
-  return MakeGarbageCollected<HTMLTextAreaElement>(document);
-}
-
 void HTMLTextAreaElement::DidAddUserAgentShadowRoot(ShadowRoot& root) {
   root.AppendChild(CreateInnerEditorElement());
 }
@@ -464,8 +460,8 @@
 
   // Since there may be comments, ignore nodes other than text nodes.
   for (Node* n = firstChild(); n; n = n->nextSibling()) {
-    if (n->IsTextNode())
-      value.Append(ToText(n)->data());
+    if (auto* text_node = DynamicTo<Text>(n))
+      value.Append(text_node->data());
   }
 
   return value.ToString();
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.h b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
index 88c44967..8bbd305ac 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
@@ -36,8 +36,6 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static HTMLTextAreaElement* Create(Document&);
-
   explicit HTMLTextAreaElement(Document&);
 
   unsigned cols() const { return cols_; }
diff --git a/third_party/blink/renderer/core/html/forms/image_input_type.cc b/third_party/blink/renderer/core/html/forms/image_input_type.cc
index 35a4b1ba..3db1b975 100644
--- a/third_party/blink/renderer/core/html/forms/image_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/image_input_type.cc
@@ -45,13 +45,9 @@
 
 using namespace html_names;
 
-inline ImageInputType::ImageInputType(HTMLInputElement& element)
+ImageInputType::ImageInputType(HTMLInputElement& element)
     : BaseButtonInputType(element), use_fallback_content_(false) {}
 
-InputType* ImageInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<ImageInputType>(element);
-}
-
 void ImageInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeImage);
 }
diff --git a/third_party/blink/renderer/core/html/forms/image_input_type.h b/third_party/blink/renderer/core/html/forms/image_input_type.h
index b9ed1e9..01d26bee 100644
--- a/third_party/blink/renderer/core/html/forms/image_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/image_input_type.h
@@ -40,8 +40,7 @@
 
 class ImageInputType final : public BaseButtonInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-  ImageInputType(HTMLInputElement&);
+  explicit ImageInputType(HTMLInputElement&);
   scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
       scoped_refptr<ComputedStyle>) override;
 
diff --git a/third_party/blink/renderer/core/html/forms/input_type.cc b/third_party/blink/renderer/core/html/forms/input_type.cc
index 9b06bd484..dd3e9c1 100644
--- a/third_party/blink/renderer/core/html/forms/input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/input_type.cc
@@ -84,27 +84,70 @@
 static std::unique_ptr<InputTypeFactoryMap> CreateInputTypeFactoryMap() {
   std::unique_ptr<InputTypeFactoryMap> map =
       std::make_unique<InputTypeFactoryMap>();
-  map->insert(input_type_names::kButton, ButtonInputType::Create);
-  map->insert(input_type_names::kCheckbox, CheckboxInputType::Create);
-  map->insert(input_type_names::kColor, ColorInputType::Create);
-  map->insert(input_type_names::kDate, DateInputType::Create);
-  map->insert(input_type_names::kDatetimeLocal, DateTimeLocalInputType::Create);
-  map->insert(input_type_names::kEmail, EmailInputType::Create);
-  map->insert(input_type_names::kFile, FileInputType::Create);
-  map->insert(input_type_names::kHidden, HiddenInputType::Create);
-  map->insert(input_type_names::kImage, ImageInputType::Create);
-  map->insert(input_type_names::kMonth, MonthInputType::Create);
-  map->insert(input_type_names::kNumber, NumberInputType::Create);
-  map->insert(input_type_names::kPassword, PasswordInputType::Create);
-  map->insert(input_type_names::kRadio, RadioInputType::Create);
-  map->insert(input_type_names::kRange, RangeInputType::Create);
-  map->insert(input_type_names::kReset, ResetInputType::Create);
-  map->insert(input_type_names::kSearch, SearchInputType::Create);
-  map->insert(input_type_names::kSubmit, SubmitInputType::Create);
-  map->insert(input_type_names::kTel, TelephoneInputType::Create);
-  map->insert(input_type_names::kTime, TimeInputType::Create);
-  map->insert(input_type_names::kUrl, URLInputType::Create);
-  map->insert(input_type_names::kWeek, WeekInputType::Create);
+  map->insert(input_type_names::kButton,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<ButtonInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kCheckbox,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<CheckboxInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kColor,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<ColorInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kDate,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<DateInputType, HTMLInputElement&>));
+  map->insert(
+      input_type_names::kDatetimeLocal,
+      reinterpret_cast<InputTypeFactoryFunction>(
+          MakeGarbageCollected<DateTimeLocalInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kEmail,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<EmailInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kFile,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<FileInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kHidden,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<HiddenInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kImage,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<ImageInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kMonth,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<MonthInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kNumber,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<NumberInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kPassword,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<PasswordInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kRadio,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<RadioInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kRange,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<RangeInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kReset,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<ResetInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kSearch,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<SearchInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kSubmit,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<SubmitInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kTel,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<TelephoneInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kTime,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<TimeInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kUrl,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<URLInputType, HTMLInputElement&>));
+  map->insert(input_type_names::kWeek,
+              reinterpret_cast<InputTypeFactoryFunction>(
+                  MakeGarbageCollected<WeekInputType, HTMLInputElement&>));
   // No need to register "text" because it is the default type.
   return map;
 }
diff --git a/third_party/blink/renderer/core/html/forms/month_input_type.cc b/third_party/blink/renderer/core/html/forms/month_input_type.cc
index 2dca735..32b4dc8 100644
--- a/third_party/blink/renderer/core/html/forms/month_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/month_input_type.cc
@@ -50,10 +50,6 @@
 static const int kMonthDefaultStepBase = 0;
 static const int kMonthStepScaleFactor = 1;
 
-InputType* MonthInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<MonthInputType>(element);
-}
-
 void MonthInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeMonth);
 }
diff --git a/third_party/blink/renderer/core/html/forms/month_input_type.h b/third_party/blink/renderer/core/html/forms/month_input_type.h
index 43d0733..a577873 100644
--- a/third_party/blink/renderer/core/html/forms/month_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/month_input_type.h
@@ -37,8 +37,6 @@
 
 class MonthInputType final : public BaseTemporalInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   explicit MonthInputType(HTMLInputElement& element)
       : BaseTemporalInputType(element) {}
 
diff --git a/third_party/blink/renderer/core/html/forms/number_input_type.cc b/third_party/blink/renderer/core/html/forms/number_input_type.cc
index 12b5b06..e6f3a8d8 100644
--- a/third_party/blink/renderer/core/html/forms/number_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/number_input_type.cc
@@ -94,10 +94,6 @@
       number_of_zero_after_decimal_point + size_of_digits);
 }
 
-InputType* NumberInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<NumberInputType>(element);
-}
-
 void NumberInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeNumber);
 }
diff --git a/third_party/blink/renderer/core/html/forms/number_input_type.h b/third_party/blink/renderer/core/html/forms/number_input_type.h
index fe94317f..fcb364e 100644
--- a/third_party/blink/renderer/core/html/forms/number_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/number_input_type.h
@@ -39,9 +39,8 @@
 
 class NumberInputType final : public TextFieldInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
-  NumberInputType(HTMLInputElement& element) : TextFieldInputType(element) {}
+  explicit NumberInputType(HTMLInputElement& element)
+      : TextFieldInputType(element) {}
 
  private:
   void CountUsage() override;
diff --git a/third_party/blink/renderer/core/html/forms/password_input_type.cc b/third_party/blink/renderer/core/html/forms/password_input_type.cc
index 0fb452d..13f82af 100644
--- a/third_party/blink/renderer/core/html/forms/password_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/password_input_type.cc
@@ -44,10 +44,6 @@
 
 namespace blink {
 
-InputType* PasswordInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<PasswordInputType>(element);
-}
-
 void PasswordInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypePassword);
   if (GetElement().FastHasAttribute(html_names::kMaxlengthAttr))
diff --git a/third_party/blink/renderer/core/html/forms/password_input_type.h b/third_party/blink/renderer/core/html/forms/password_input_type.h
index c113962..33997fcf 100644
--- a/third_party/blink/renderer/core/html/forms/password_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/password_input_type.h
@@ -37,8 +37,6 @@
 
 class PasswordInputType final : public BaseTextInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   explicit PasswordInputType(HTMLInputElement& element)
       : BaseTextInputType(element) {}
 
diff --git a/third_party/blink/renderer/core/html/forms/radio_input_type.cc b/third_party/blink/renderer/core/html/forms/radio_input_type.cc
index 390b1424..730db85 100644
--- a/third_party/blink/renderer/core/html/forms/radio_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/radio_input_type.cc
@@ -46,10 +46,6 @@
 
 }  // namespace
 
-InputType* RadioInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<RadioInputType>(element);
-}
-
 void RadioInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeRadio);
 }
diff --git a/third_party/blink/renderer/core/html/forms/radio_input_type.h b/third_party/blink/renderer/core/html/forms/radio_input_type.h
index c790686..5c0b43d 100644
--- a/third_party/blink/renderer/core/html/forms/radio_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/radio_input_type.h
@@ -38,7 +38,6 @@
 
 class RadioInputType final : public BaseCheckableInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
   CORE_EXPORT static HTMLInputElement* NextRadioButtonInGroup(HTMLInputElement*,
                                                               bool forward);
 
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.cc b/third_party/blink/renderer/core/html/forms/range_input_type.cc
index e3d19561..a43070f 100644
--- a/third_party/blink/renderer/core/html/forms/range_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/range_input_type.cc
@@ -72,10 +72,6 @@
   return proposed_value >= minimum ? proposed_value : minimum;
 }
 
-InputType* RangeInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<RangeInputType>(element);
-}
-
 RangeInputType::RangeInputType(HTMLInputElement& element)
     : InputType(element),
       InputTypeView(element),
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.h b/third_party/blink/renderer/core/html/forms/range_input_type.h
index ebee693..1ff7566 100644
--- a/third_party/blink/renderer/core/html/forms/range_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/range_input_type.h
@@ -43,9 +43,7 @@
   USING_GARBAGE_COLLECTED_MIXIN(RangeInputType);
 
  public:
-  static InputType* Create(HTMLInputElement&);
-
-  RangeInputType(HTMLInputElement&);
+  explicit RangeInputType(HTMLInputElement&);
 
   void Trace(Visitor*) override;
   using InputType::GetElement;
diff --git a/third_party/blink/renderer/core/html/forms/reset_input_type.cc b/third_party/blink/renderer/core/html/forms/reset_input_type.cc
index 8d69a7d..73c5cf0 100644
--- a/third_party/blink/renderer/core/html/forms/reset_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/reset_input_type.cc
@@ -40,10 +40,6 @@
 
 namespace blink {
 
-InputType* ResetInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<ResetInputType>(element);
-}
-
 void ResetInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeReset);
 }
diff --git a/third_party/blink/renderer/core/html/forms/reset_input_type.h b/third_party/blink/renderer/core/html/forms/reset_input_type.h
index 6bafa1b..1672ed9 100644
--- a/third_party/blink/renderer/core/html/forms/reset_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/reset_input_type.h
@@ -37,9 +37,8 @@
 
 class ResetInputType final : public BaseButtonInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
-  ResetInputType(HTMLInputElement& element) : BaseButtonInputType(element) {}
+  explicit ResetInputType(HTMLInputElement& element)
+      : BaseButtonInputType(element) {}
 
  private:
   void CountUsage() override;
diff --git a/third_party/blink/renderer/core/html/forms/search_input_type.cc b/third_party/blink/renderer/core/html/forms/search_input_type.cc
index 65b60e9f7..2a2e080 100644
--- a/third_party/blink/renderer/core/html/forms/search_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/search_input_type.cc
@@ -46,17 +46,13 @@
 
 using namespace html_names;
 
-inline SearchInputType::SearchInputType(HTMLInputElement& element)
+SearchInputType::SearchInputType(HTMLInputElement& element)
     : BaseTextInputType(element),
       search_event_timer_(
           element.GetDocument().GetTaskRunner(TaskType::kUserInteraction),
           this,
           &SearchInputType::SearchEventTimerFired) {}
 
-InputType* SearchInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<SearchInputType>(element);
-}
-
 void SearchInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeSearch);
 }
diff --git a/third_party/blink/renderer/core/html/forms/search_input_type.h b/third_party/blink/renderer/core/html/forms/search_input_type.h
index b27f3f0..34a6f6b 100644
--- a/third_party/blink/renderer/core/html/forms/search_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/search_input_type.h
@@ -38,8 +38,6 @@
 
 class SearchInputType final : public BaseTextInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   SearchInputType(HTMLInputElement&);
 
  private:
diff --git a/third_party/blink/renderer/core/html/forms/submit_input_type.cc b/third_party/blink/renderer/core/html/forms/submit_input_type.cc
index 0cf4396..6ab4816 100644
--- a/third_party/blink/renderer/core/html/forms/submit_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/submit_input_type.cc
@@ -41,9 +41,9 @@
 
 namespace blink {
 
-InputType* SubmitInputType::Create(HTMLInputElement& element) {
+SubmitInputType::SubmitInputType(HTMLInputElement& element)
+    : BaseButtonInputType(element) {
   UseCounter::Count(element.GetDocument(), WebFeature::kInputTypeSubmit);
-  return MakeGarbageCollected<SubmitInputType>(element);
 }
 
 const AtomicString& SubmitInputType::FormControlType() const {
diff --git a/third_party/blink/renderer/core/html/forms/submit_input_type.h b/third_party/blink/renderer/core/html/forms/submit_input_type.h
index 7dc51ffe..bacca2800 100644
--- a/third_party/blink/renderer/core/html/forms/submit_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/submit_input_type.h
@@ -37,9 +37,7 @@
 
 class SubmitInputType final : public BaseButtonInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
-  SubmitInputType(HTMLInputElement& element) : BaseButtonInputType(element) {}
+  explicit SubmitInputType(HTMLInputElement& element);
 
  private:
   const AtomicString& FormControlType() const override;
diff --git a/third_party/blink/renderer/core/html/forms/telephone_input_type.cc b/third_party/blink/renderer/core/html/forms/telephone_input_type.cc
index 2dde47f..908e990 100644
--- a/third_party/blink/renderer/core/html/forms/telephone_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/telephone_input_type.cc
@@ -35,10 +35,6 @@
 
 namespace blink {
 
-InputType* TelephoneInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<TelephoneInputType>(element);
-}
-
 void TelephoneInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeTel);
 }
diff --git a/third_party/blink/renderer/core/html/forms/telephone_input_type.h b/third_party/blink/renderer/core/html/forms/telephone_input_type.h
index 6ffc76b..1584006b 100644
--- a/third_party/blink/renderer/core/html/forms/telephone_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/telephone_input_type.h
@@ -37,9 +37,8 @@
 
 class TelephoneInputType final : public BaseTextInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
-  TelephoneInputType(HTMLInputElement& element) : BaseTextInputType(element) {}
+  explicit TelephoneInputType(HTMLInputElement& element)
+      : BaseTextInputType(element) {}
 
  private:
   void CountUsage() override;
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc
index a747afa..8699aba 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -366,11 +366,10 @@
       continue;
     }
 
-    if (node.IsTextNode()) {
-      Text& text = ToText(node);
-      if (remaining_characters_to_move_forward < text.length())
-        return Position(&text, remaining_characters_to_move_forward);
-      remaining_characters_to_move_forward -= text.length();
+    if (auto* text = DynamicTo<Text>(node)) {
+      if (remaining_characters_to_move_forward < text->length())
+        return Position(text, remaining_characters_to_move_forward);
+      remaining_characters_to_move_forward -= text->length();
       last_br_or_text = &node;
       continue;
     }
@@ -401,8 +400,8 @@
 
   for (Node* node = start_node; node;
        node = NodeTraversal::Previous(*node, inner_editor)) {
-    if (node->IsTextNode()) {
-      int length = ToText(*node).length();
+    if (auto* text_node = DynamicTo<Text>(node)) {
+      int length = text_node->length();
       if (node == passed_position.ComputeContainerNode())
         index += std::min(length, passed_position.OffsetInContainerNode());
       else
@@ -795,11 +794,11 @@
   if (inner_editor->GetLayoutObject() &&
       !inner_editor->GetLayoutObject()->Style()->PreserveNewline())
     return;
-  Node* last_child = inner_editor->lastChild();
-  if (!last_child || !last_child->IsTextNode())
+  auto* last_child_text_node = DynamicTo<Text>(inner_editor->lastChild());
+  if (!last_child_text_node)
     return;
-  if (ToText(last_child)->data().EndsWith('\n') ||
-      ToText(last_child)->data().EndsWith('\r'))
+  if (last_child_text_node->data().EndsWith('\n') ||
+      last_child_text_node->data().EndsWith('\r'))
     inner_editor->AppendChild(CreatePlaceholderBreakElement());
 }
 
@@ -846,12 +845,11 @@
   if (!inner_editor->HasChildren())
     return g_empty_string;
   Node& first_child = *inner_editor->firstChild();
-  if (first_child.IsTextNode()) {
+  if (auto* first_child_text_node = DynamicTo<Text>(first_child)) {
     Node* second_child = first_child.nextSibling();
-    if (!second_child)
-      return ToText(first_child).data();
-    if (!second_child->nextSibling() && IsHTMLBRElement(*second_child))
-      return ToText(first_child).data();
+    if (!second_child ||
+        (!second_child->nextSibling() && IsHTMLBRElement(*second_child)))
+      return first_child_text_node->data();
   } else if (!first_child.nextSibling() && IsHTMLBRElement(first_child)) {
     return g_empty_string;
   }
@@ -862,8 +860,8 @@
       DCHECK_EQ(&node, inner_editor->lastChild());
       if (&node != inner_editor->lastChild())
         result.Append(kNewlineCharacter);
-    } else if (node.IsTextNode()) {
-      result.Append(ToText(node).data());
+    } else if (auto* text_node = DynamicTo<Text>(node)) {
+      result.Append(text_node->data());
     }
   }
   return result.ToString();
@@ -913,8 +911,8 @@
       DCHECK_EQ(&node, inner_text->lastChild());
       if (&node != inner_text->lastChild())
         result.Append(kNewlineCharacter);
-    } else if (node.IsTextNode()) {
-      String data = ToText(node).data();
+    } else if (auto* text_node = DynamicTo<Text>(node)) {
+      String data = text_node->data();
       unsigned length = data.length();
       unsigned position = 0;
       while (break_node == node && break_offset <= length) {
diff --git a/third_party/blink/renderer/core/html/forms/time_input_type.cc b/third_party/blink/renderer/core/html/forms/time_input_type.cc
index 05d60c1..eaabf37 100644
--- a/third_party/blink/renderer/core/html/forms/time_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/time_input_type.cc
@@ -55,10 +55,6 @@
 TimeInputType::TimeInputType(HTMLInputElement& element)
     : BaseTemporalInputType(element) {}
 
-InputType* TimeInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<TimeInputType>(element);
-}
-
 void TimeInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeTime);
 }
diff --git a/third_party/blink/renderer/core/html/forms/time_input_type.h b/third_party/blink/renderer/core/html/forms/time_input_type.h
index d5d74cf..58711ec4 100644
--- a/third_party/blink/renderer/core/html/forms/time_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/time_input_type.h
@@ -37,8 +37,6 @@
 
 class TimeInputType final : public BaseTemporalInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   explicit TimeInputType(HTMLInputElement&);
 
  private:
diff --git a/third_party/blink/renderer/core/html/forms/url_input_type.cc b/third_party/blink/renderer/core/html/forms/url_input_type.cc
index c58aa25..d672297 100644
--- a/third_party/blink/renderer/core/html/forms/url_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/url_input_type.cc
@@ -38,10 +38,6 @@
 
 namespace blink {
 
-InputType* URLInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<URLInputType>(element);
-}
-
 void URLInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeURL);
 }
diff --git a/third_party/blink/renderer/core/html/forms/url_input_type.h b/third_party/blink/renderer/core/html/forms/url_input_type.h
index 8d1ec15..bbbd410 100644
--- a/third_party/blink/renderer/core/html/forms/url_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/url_input_type.h
@@ -37,8 +37,6 @@
 
 class URLInputType final : public BaseTextInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   URLInputType(HTMLInputElement& element) : BaseTextInputType(element) {}
 
  private:
diff --git a/third_party/blink/renderer/core/html/forms/week_input_type.cc b/third_party/blink/renderer/core/html/forms/week_input_type.cc
index 6a27534..c78dbcdd 100644
--- a/third_party/blink/renderer/core/html/forms/week_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/week_input_type.cc
@@ -48,10 +48,6 @@
 static const int kWeekDefaultStep = 1;
 static const int kWeekStepScaleFactor = 604800000;
 
-InputType* WeekInputType::Create(HTMLInputElement& element) {
-  return MakeGarbageCollected<WeekInputType>(element);
-}
-
 void WeekInputType::CountUsage() {
   CountUsageIfVisible(WebFeature::kInputTypeWeek);
 }
diff --git a/third_party/blink/renderer/core/html/forms/week_input_type.h b/third_party/blink/renderer/core/html/forms/week_input_type.h
index f4ed68e..783aeff 100644
--- a/third_party/blink/renderer/core/html/forms/week_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/week_input_type.h
@@ -37,8 +37,6 @@
 
 class WeekInputType final : public BaseTemporalInputType {
  public:
-  static InputType* Create(HTMLInputElement&);
-
   explicit WeekInputType(HTMLInputElement& element)
       : BaseTemporalInputType(element) {}
 
diff --git a/third_party/blink/renderer/core/html/html_all_collection.cc b/third_party/blink/renderer/core/html/html_all_collection.cc
index b18da7f..bf74ee9 100644
--- a/third_party/blink/renderer/core/html/html_all_collection.cc
+++ b/third_party/blink/renderer/core/html/html_all_collection.cc
@@ -29,12 +29,6 @@
 
 namespace blink {
 
-HTMLAllCollection* HTMLAllCollection::Create(ContainerNode& node,
-                                             CollectionType type) {
-  DCHECK_EQ(type, kDocAll);
-  return MakeGarbageCollected<HTMLAllCollection>(node);
-}
-
 HTMLAllCollection::HTMLAllCollection(ContainerNode& node)
     : HTMLCollection(node, kDocAll, kDoesNotOverrideItemAfter) {}
 
diff --git a/third_party/blink/renderer/core/html/html_all_collection.h b/third_party/blink/renderer/core/html/html_all_collection.h
index 8dcf8bb..c01c8bf 100644
--- a/third_party/blink/renderer/core/html/html_all_collection.h
+++ b/third_party/blink/renderer/core/html/html_all_collection.h
@@ -37,8 +37,6 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static HTMLAllCollection* Create(ContainerNode&, CollectionType);
-
   explicit HTMLAllCollection(ContainerNode&);
   HTMLAllCollection(ContainerNode&, CollectionType);
   ~HTMLAllCollection() override;
diff --git a/third_party/blink/renderer/core/html/html_collection.cc b/third_party/blink/renderer/core/html/html_collection.cc
index c6f2b64..b13e8fa8 100644
--- a/third_party/blink/renderer/core/html/html_collection.cc
+++ b/third_party/blink/renderer/core/html/html_collection.cc
@@ -191,12 +191,6 @@
   GetDocument().RegisterNodeList(this);
 }
 
-HTMLCollection* HTMLCollection::Create(ContainerNode& base,
-                                       CollectionType type) {
-  return MakeGarbageCollected<HTMLCollection>(base, type,
-                                              kDoesNotOverrideItemAfter);
-}
-
 HTMLCollection::~HTMLCollection() = default;
 
 void HTMLCollection::InvalidateCache(Document* old_document) const {
diff --git a/third_party/blink/renderer/core/html/html_collection.h b/third_party/blink/renderer/core/html/html_collection.h
index 8e768da..d1388a8 100644
--- a/third_party/blink/renderer/core/html/html_collection.h
+++ b/third_party/blink/renderer/core/html/html_collection.h
@@ -76,7 +76,6 @@
     kDoesNotOverrideItemAfter,
   };
 
-  static HTMLCollection* Create(ContainerNode& base, CollectionType);
   HTMLCollection(ContainerNode& base,
                  CollectionType,
                  ItemAfterOverrideType = kDoesNotOverrideItemAfter);
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc
index 88f41ff..deed25cb 100644
--- a/third_party/blink/renderer/core/html/html_element.cc
+++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -787,11 +787,13 @@
   parent->ReplaceChild(new_child, this, exception_state);
 
   Node* node = next ? next->previousSibling() : nullptr;
-  if (!exception_state.HadException() && node && node->IsTextNode())
-    MergeWithNextTextNode(ToText(node), exception_state);
+  auto* next_text_node = DynamicTo<Text>(node);
+  if (!exception_state.HadException() && next_text_node)
+    MergeWithNextTextNode(next_text_node, exception_state);
 
+  auto* prev_text_node = DynamicTo<Text>(prev);
   if (!exception_state.HadException() && prev && prev->IsTextNode())
-    MergeWithNextTextNode(ToText(prev), exception_state);
+    MergeWithNextTextNode(prev_text_node, exception_state);
 }
 
 void HTMLElement::ApplyAlignmentAttributeToStyle(
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc
index c73037f..1bb9368a 100644
--- a/third_party/blink/renderer/core/html/html_iframe_element.cc
+++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -290,16 +290,17 @@
   if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
     // If the frame is sandboxed at all, then warn if feature policy attributes
     // will override the sandbox attributes.
-    // TODO(ekaramad): Add similar messages for all the converted sandbox flags.
     if (messages && (sandbox_flags_converted_to_feature_policies_ &
                      WebSandboxFlags::kNavigation) != WebSandboxFlags::kNone) {
-      if ((sandbox_flags_converted_to_feature_policies_ &
-           WebSandboxFlags::kForms) == WebSandboxFlags::kNone &&
-          IsFeatureDeclared(mojom::FeaturePolicyFeature::kFormSubmission,
-                            container_policy)) {
-        messages->push_back(
-            "Allow and Sandbox attributes both mention forms. Allow will take "
-            "precedence.");
+      for (const auto& pair : SandboxFlagsWithFeaturePolicies()) {
+        if ((sandbox_flags_converted_to_feature_policies_ & pair.first) !=
+                WebSandboxFlags::kNone &&
+            IsFeatureDeclared(pair.second, container_policy)) {
+          messages->push_back(String::Format(
+              "Allow and Sandbox attributes both mention '%s'. Allow will take "
+              "precedence.",
+              GetNameForFeature(pair.second).Utf8().data()));
+        }
       }
     }
     ApplySandboxFlagsToParsedFeaturePolicy(
diff --git a/third_party/blink/renderer/core/html/html_object_element.cc b/third_party/blink/renderer/core/html/html_object_element.cc
index 955575b401..d60738d 100644
--- a/third_party/blink/renderer/core/html/html_object_element.cc
+++ b/third_party/blink/renderer/core/html/html_object_element.cc
@@ -192,8 +192,9 @@
   for (Node* child = firstChild(); child; child = child->nextSibling()) {
     // Ignore whitespace-only text, and <param> tags, any other content is
     // fallback content.
-    if (child->IsTextNode()) {
-      if (!ToText(child)->ContainsOnlyWhitespaceOrEmpty())
+    auto* child_text_node = DynamicTo<Text>(child);
+    if (child_text_node) {
+      if (!child_text_node->ContainsOnlyWhitespaceOrEmpty())
         return true;
     } else if (!IsHTMLParamElement(*child)) {
       return true;
diff --git a/third_party/blink/renderer/core/html/media/html_audio_element.cc b/third_party/blink/renderer/core/html/media/html_audio_element.cc
index 79368e1..2f27358 100644
--- a/third_party/blink/renderer/core/html/media/html_audio_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_audio_element.cc
@@ -38,10 +38,6 @@
   UpdateStateIfNeeded();
 }
 
-HTMLAudioElement* HTMLAudioElement::Create(Document& document) {
-  return MakeGarbageCollected<HTMLAudioElement>(document);
-}
-
 HTMLAudioElement* HTMLAudioElement::CreateForJSConstructor(
     Document& document,
     const AtomicString& src) {
diff --git a/third_party/blink/renderer/core/html/media/html_audio_element.h b/third_party/blink/renderer/core/html/media/html_audio_element.h
index c345675..bafd92f 100644
--- a/third_party/blink/renderer/core/html/media/html_audio_element.h
+++ b/third_party/blink/renderer/core/html/media/html_audio_element.h
@@ -38,7 +38,6 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static HTMLAudioElement* Create(Document&);
   static HTMLAudioElement* CreateForJSConstructor(
       Document&,
       const AtomicString& src = g_null_atom);
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_controls_list.h b/third_party/blink/renderer/core/html/media/html_media_element_controls_list.h
index d7787fa9..6fa86cb 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element_controls_list.h
+++ b/third_party/blink/renderer/core/html/media/html_media_element_controls_list.h
@@ -15,10 +15,6 @@
 
 class CORE_EXPORT HTMLMediaElementControlsList final : public DOMTokenList {
  public:
-  static HTMLMediaElementControlsList* Create(HTMLMediaElement* element) {
-    return MakeGarbageCollected<HTMLMediaElementControlsList>(element);
-  }
-
   explicit HTMLMediaElementControlsList(HTMLMediaElement*);
 
   // Whether the list dictates to hide a certain control.
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_test.cc b/third_party/blink/renderer/core/html/media/html_media_element_test.cc
index 5efa46c1..783b3fc 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element_test.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element_test.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/renderer/core/html/track/video_track_list.h"
 #include "third_party/blink/renderer/core/loader/empty_clients.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/network/network_state_notifier.h"
 #include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -91,10 +92,12 @@
             std::move(mock_media_player)),
         nullptr);
 
-    if (GetParam() == MediaTestParam::kAudio)
-      media_ = HTMLAudioElement::Create(dummy_page_holder_->GetDocument());
-    else
+    if (GetParam() == MediaTestParam::kAudio) {
+      media_ = MakeGarbageCollected<HTMLAudioElement>(
+          dummy_page_holder_->GetDocument());
+    } else {
       media_ = HTMLVideoElement::Create(dummy_page_holder_->GetDocument());
+    }
   }
 
   HTMLMediaElement* Media() const { return media_.Get(); }
diff --git a/third_party/blink/renderer/core/html/media/html_media_test_helper.h b/third_party/blink/renderer/core/html/media/html_media_test_helper.h
index 93d163a..4a35eb1ed 100644
--- a/third_party/blink/renderer/core/html/media/html_media_test_helper.h
+++ b/third_party/blink/renderer/core/html/media/html_media_test_helper.h
@@ -16,9 +16,6 @@
 // WebMediaPlayerimplementation.
 class MediaStubLocalFrameClient : public EmptyLocalFrameClient {
  public:
-  // Creates a LocalFrameClient that will use the given media player.
-  static MediaStubLocalFrameClient* Create(std::unique_ptr<WebMediaPlayer>);
-
   explicit MediaStubLocalFrameClient(std::unique_ptr<WebMediaPlayer>);
 
   std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer(
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
index e4602b3..2fd6bb0ee 100644
--- a/third_party/blink/renderer/core/html/portal/html_portal_element.cc
+++ b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
 #include "third_party/blink/renderer/core/html/portal/document_portals.h"
 #include "third_party/blink/renderer/core/html/portal/portal_activate_options.h"
+#include "third_party/blink/renderer/core/html/portal/portal_post_message_helper.h"
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/inspector/thread_debugger.h"
@@ -131,42 +132,6 @@
   return msg;
 }
 
-BlinkTransferableMessage CreateMessageForPostMessage(
-    ScriptState* script_state,
-    const ScriptValue& message,
-    const WindowPostMessageOptions* options,
-    ExceptionState& exception_state) {
-  BlinkTransferableMessage transferable_message;
-  Transferables transferables;
-  scoped_refptr<SerializedScriptValue> serialized_message =
-      PostMessageHelper::SerializeMessageByMove(script_state->GetIsolate(),
-                                                message, options, transferables,
-                                                exception_state);
-  if (exception_state.HadException())
-    return {};
-  DCHECK(serialized_message);
-  transferable_message.message = serialized_message;
-
-  // Disentangle the port in preparation for sending it to the remote context.
-  auto* execution_context = ExecutionContext::From(script_state);
-  transferable_message.ports = MessagePort::DisentanglePorts(
-      execution_context, transferables.message_ports, exception_state);
-  if (exception_state.HadException())
-    return {};
-
-  if (ThreadDebugger* debugger =
-          ThreadDebugger::From(script_state->GetIsolate())) {
-    transferable_message.sender_stack_trace_id =
-        debugger->StoreCurrentStackTrace("postMessage");
-  }
-
-  transferable_message.user_activation =
-      PostMessageHelper::CreateUserActivationSnapshot(execution_context,
-                                                      options);
-
-  return transferable_message;
-}
-
 }  // namespace
 
 ScriptPromise HTMLPortalElement::activate(ScriptState* script_state,
@@ -261,14 +226,15 @@
     return;
   }
 
-  scoped_refptr<const SecurityOrigin> target_origin = nullptr;
-  if (options->targetOrigin() == "/")
-    target_origin = GetDocument().GetSecurityOrigin();
-  else if (options->targetOrigin() != "*")
-    target_origin = SecurityOrigin::CreateFromString(options->targetOrigin());
+  scoped_refptr<const SecurityOrigin> target_origin =
+      PostMessageHelper::GetTargetOrigin(options, GetDocument(),
+                                         exception_state);
+  if (exception_state.HadException())
+    return;
 
-  BlinkTransferableMessage transferable_message = CreateMessageForPostMessage(
-      script_state, message, options, exception_state);
+  BlinkTransferableMessage transferable_message =
+      PortalPostMessageHelper::CreateMessage(script_state, message, options,
+                                             exception_state);
   if (exception_state.HadException())
     return;
 
@@ -276,21 +242,31 @@
                                   target_origin);
 }
 
+EventListener* HTMLPortalElement::onmessage() {
+  return GetAttributeEventListener(event_type_names::kMessage);
+}
+
+void HTMLPortalElement::setOnmessage(EventListener* listener) {
+  SetAttributeEventListener(event_type_names::kMessage, listener);
+}
+
+EventListener* HTMLPortalElement::onmessageerror() {
+  return GetAttributeEventListener(event_type_names::kMessageerror);
+}
+
+void HTMLPortalElement::setOnmessageerror(EventListener* listener) {
+  SetAttributeEventListener(event_type_names::kMessageerror, listener);
+}
+
 void HTMLPortalElement::ForwardMessageFromGuest(
-    const String& message,
+    BlinkTransferableMessage message,
     const scoped_refptr<const SecurityOrigin>& source_origin,
     const scoped_refptr<const SecurityOrigin>& target_origin) {
   if (!portal_ptr_)
     return;
 
-  if (target_origin && !target_origin->IsSameSchemeHostPort(
-                           GetExecutionContext()->GetSecurityOrigin())) {
-    return;
-  }
-
-  MessageEvent* event =
-      MessageEvent::Create(message, source_origin->ToString());
-  DispatchEvent(*event);
+  PortalPostMessageHelper::CreateAndDispatchMessageEvent(
+      this, std::move(message), source_origin, target_origin);
 }
 
 HTMLPortalElement::InsertionNotificationRequest HTMLPortalElement::InsertedInto(
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.h b/third_party/blink/renderer/core/html/portal/html_portal_element.h
index fc12c5ae..f7c5c94c 100644
--- a/third_party/blink/renderer/core/html/portal/html_portal_element.h
+++ b/third_party/blink/renderer/core/html/portal/html_portal_element.h
@@ -54,10 +54,14 @@
                    const ScriptValue& message,
                    const WindowPostMessageOptions* options,
                    ExceptionState& exception_state);
+  EventListener* onmessage();
+  void setOnmessage(EventListener* listener);
+  EventListener* onmessageerror();
+  void setOnmessageerror(EventListener* listener);
 
   // blink::mojom::PortalClient implementation
   void ForwardMessageFromGuest(
-      const String& message,
+      BlinkTransferableMessage message,
       const scoped_refptr<const SecurityOrigin>& source_origin,
       const scoped_refptr<const SecurityOrigin>& target_origin) override;
 
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.idl b/third_party/blink/renderer/core/html/portal/html_portal_element.idl
index e0b1eae..cb1b02f 100644
--- a/third_party/blink/renderer/core/html/portal/html_portal_element.idl
+++ b/third_party/blink/renderer/core/html/portal/html_portal_element.idl
@@ -11,4 +11,7 @@
   [CallWith=ScriptState, RaisesException] void postMessage(any message, DOMString targetOrigin,
                                      optional sequence<object> transfer = []);
   [CallWith=ScriptState, RaisesException] void postMessage(any message, optional WindowPostMessageOptions options);
+
+  attribute EventHandler onmessage;
+  attribute EventHandler onmessageerror;
 };
diff --git a/third_party/blink/renderer/core/html/portal/portal_host.cc b/third_party/blink/renderer/core/html/portal/portal_host.cc
index ac97354..0754209 100644
--- a/third_party/blink/renderer/core/html/portal/portal_host.cc
+++ b/third_party/blink/renderer/core/html/portal/portal_host.cc
@@ -7,15 +7,14 @@
 #include <utility>
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
 #include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/events/message_event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
-#include "third_party/blink/renderer/core/frame/user_activation.h"
 #include "third_party/blink/renderer/core/frame/window_post_message_options.h"
 #include "third_party/blink/renderer/core/html/portal/dom_window_portal_host.h"
-#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
+#include "third_party/blink/renderer/core/html/portal/portal_post_message_helper.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
 
@@ -63,7 +62,8 @@
   portal_host_ptr_.reset();
 }
 
-void PortalHost::postMessage(const String& message,
+void PortalHost::postMessage(ScriptState* script_state,
+                             const ScriptValue& message,
                              const String& target_origin,
                              Vector<ScriptValue>& transfer,
                              ExceptionState& exception_state) {
@@ -71,10 +71,11 @@
   options->setTargetOrigin(target_origin);
   if (!transfer.IsEmpty())
     options->setTransfer(transfer);
-  postMessage(message, options, exception_state);
+  postMessage(script_state, message, options, exception_state);
 }
 
-void PortalHost::postMessage(const String& message,
+void PortalHost::postMessage(ScriptState* script_state,
+                             const ScriptValue& message,
                              const WindowPostMessageOptions* options,
                              ExceptionState& exception_state) {
   if (!DOMWindowPortalHost::ShouldExposePortalHost(*GetSupplementable())) {
@@ -84,43 +85,45 @@
     return;
   }
 
-  scoped_refptr<const SecurityOrigin> target_origin;
-  if (options->targetOrigin() == "/")
-    target_origin = GetDocument()->GetSecurityOrigin();
-  else if (options->targetOrigin() != "*")
-    target_origin = SecurityOrigin::CreateFromString(options->targetOrigin());
+  scoped_refptr<const SecurityOrigin> target_origin =
+      PostMessageHelper::GetTargetOrigin(options, *GetDocument(),
+                                         exception_state);
+  if (exception_state.HadException())
+    return;
 
-  GetPortalHostInterface().PostMessageToHost(message, target_origin);
+  BlinkTransferableMessage transferable_message =
+      PortalPostMessageHelper::CreateMessage(script_state, message, options,
+                                             exception_state);
+  if (exception_state.HadException())
+    return;
+
+  GetPortalHostInterface().PostMessageToHost(std::move(transferable_message),
+                                             target_origin);
+}
+
+EventListener* PortalHost::onmessage() {
+  return GetAttributeEventListener(event_type_names::kMessage);
+}
+
+void PortalHost::setOnmessage(EventListener* listener) {
+  SetAttributeEventListener(event_type_names::kMessage, listener);
+}
+
+EventListener* PortalHost::onmessageerror() {
+  return GetAttributeEventListener(event_type_names::kMessageerror);
+}
+
+void PortalHost::setOnmessageerror(EventListener* listener) {
+  SetAttributeEventListener(event_type_names::kMessageerror, listener);
 }
 
 void PortalHost::ReceiveMessage(
     BlinkTransferableMessage message,
     scoped_refptr<const SecurityOrigin> source_origin,
     scoped_refptr<const SecurityOrigin> target_origin) {
-  DCHECK(GetSupplementable()->document()->GetPage()->InsidePortal());
-  if (target_origin && !target_origin->IsSameSchemeHostPort(
-                           GetExecutionContext()->GetSecurityOrigin())) {
-    return;
-  }
-
-  UserActivation* user_activation = nullptr;
-  if (message.user_activation) {
-    user_activation = MakeGarbageCollected<UserActivation>(
-        message.user_activation->has_been_active,
-        message.user_activation->was_active);
-  }
-
-  MessageEvent* event = MessageEvent::Create(message.ports, message.message,
-                                             source_origin->ToString(),
-                                             String(), this, user_activation);
-  event->EntangleMessagePorts(GetExecutionContext());
-
-  ThreadDebugger* debugger = MainThreadDebugger::Instance();
-  if (debugger)
-    debugger->ExternalAsyncTaskStarted(message.sender_stack_trace_id);
-  DispatchEvent(*event);
-  if (debugger)
-    debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id);
+  DCHECK(GetDocument()->GetPage()->InsidePortal());
+  PortalPostMessageHelper::CreateAndDispatchMessageEvent(
+      this, std::move(message), source_origin, target_origin);
 }
 
 mojom::blink::PortalHost& PortalHost::GetPortalHostInterface() {
diff --git a/third_party/blink/renderer/core/html/portal/portal_host.h b/third_party/blink/renderer/core/html/portal/portal_host.h
index aa11630..9fa6c67e 100644
--- a/third_party/blink/renderer/core/html/portal/portal_host.h
+++ b/third_party/blink/renderer/core/html/portal/portal_host.h
@@ -44,13 +44,19 @@
   void OnPortalActivated();
 
   // idl implementation
-  void postMessage(const String& message,
+  void postMessage(ScriptState* script_state,
+                   const ScriptValue& message,
                    const String& target_origin,
                    Vector<ScriptValue>& transfer,
                    ExceptionState& exception_state);
-  void postMessage(const String& message,
+  void postMessage(ScriptState* script_state,
+                   const ScriptValue& message,
                    const WindowPostMessageOptions* options,
                    ExceptionState& exception_state);
+  EventListener* onmessage();
+  void setOnmessage(EventListener* listener);
+  EventListener* onmessageerror();
+  void setOnmessageerror(EventListener* listener);
 
   void ReceiveMessage(BlinkTransferableMessage message,
                       scoped_refptr<const SecurityOrigin> source_origin,
diff --git a/third_party/blink/renderer/core/html/portal/portal_host.idl b/third_party/blink/renderer/core/html/portal/portal_host.idl
index 364f233..ced86df5 100644
--- a/third_party/blink/renderer/core/html/portal/portal_host.idl
+++ b/third_party/blink/renderer/core/html/portal/portal_host.idl
@@ -6,8 +6,11 @@
 
 [Exposed=Window, RuntimeEnabled=Portals]
 interface PortalHost : EventTarget {
-  [RaisesException] void postMessage(DOMString message, DOMString targetOrigin,
-                                     optional sequence<object> transfer = []);
-  [RaisesException] void postMessage(DOMString message,
-                                     optional WindowPostMessageOptions options);
+  [RaisesException, CallWith=ScriptState] void postMessage(any message, DOMString targetOrigin,
+                                                           optional sequence<object> transfer = []);
+  [RaisesException, CallWith=ScriptState] void postMessage(any message,
+                                                           optional WindowPostMessageOptions options);
+
+  attribute EventHandler onmessage;
+  attribute EventHandler onmessageerror;
 };
diff --git a/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc b/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc
new file mode 100644
index 0000000..82e04cc
--- /dev/null
+++ b/third_party/blink/renderer/core/html/portal/portal_post_message_helper.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/html/portal/portal_post_message_helper.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
+#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h"
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/events/message_event.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/frame/user_activation.h"
+#include "third_party/blink/renderer/core/frame/window_post_message_options.h"
+#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
+#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
+#include "third_party/blink/renderer/core/inspector/thread_debugger.h"
+#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
+#include "third_party/blink/renderer/core/messaging/message_port.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+
+namespace blink {
+
+// static
+BlinkTransferableMessage PortalPostMessageHelper::CreateMessage(
+    ScriptState* script_state,
+    const ScriptValue& message,
+    const WindowPostMessageOptions* options,
+    ExceptionState& exception_state) {
+  BlinkTransferableMessage transferable_message;
+  Transferables transferables;
+  scoped_refptr<SerializedScriptValue> serialized_message =
+      PostMessageHelper::SerializeMessageByMove(script_state->GetIsolate(),
+                                                message, options, transferables,
+                                                exception_state);
+  if (exception_state.HadException())
+    return {};
+  DCHECK(serialized_message);
+  transferable_message.message = serialized_message;
+
+  // Disentangle the port in preparation for sending it to the remote context.
+  auto* execution_context = ExecutionContext::From(script_state);
+  transferable_message.ports = MessagePort::DisentanglePorts(
+      execution_context, transferables.message_ports, exception_state);
+  if (exception_state.HadException())
+    return {};
+
+  if (ThreadDebugger* debugger =
+          ThreadDebugger::From(script_state->GetIsolate())) {
+    transferable_message.sender_stack_trace_id =
+        debugger->StoreCurrentStackTrace("postMessage");
+  }
+
+  transferable_message.user_activation =
+      PostMessageHelper::CreateUserActivationSnapshot(execution_context,
+                                                      options);
+
+  return transferable_message;
+}
+
+// static
+void PortalPostMessageHelper::CreateAndDispatchMessageEvent(
+    EventTarget* event_target,
+    BlinkTransferableMessage message,
+    scoped_refptr<const SecurityOrigin> source_origin,
+    scoped_refptr<const SecurityOrigin> target_origin) {
+  DCHECK(event_target->ToPortalHost() ||
+         (event_target->ToNode() &&
+          ToHTMLPortalElementOrNull(event_target->ToNode())));
+
+  if (target_origin &&
+      !target_origin->IsSameSchemeHostPort(
+          event_target->GetExecutionContext()->GetSecurityOrigin())) {
+    return;
+  }
+
+  UserActivation* user_activation = nullptr;
+  if (message.user_activation) {
+    user_activation = MakeGarbageCollected<UserActivation>(
+        message.user_activation->has_been_active,
+        message.user_activation->was_active);
+  }
+
+  MessageEvent* event = MessageEvent::Create(
+      message.ports, message.message, source_origin->ToString(), String(),
+      event_target, user_activation);
+  event->EntangleMessagePorts(event_target->GetExecutionContext());
+
+  ThreadDebugger* debugger = MainThreadDebugger::Instance();
+  if (debugger)
+    debugger->ExternalAsyncTaskStarted(message.sender_stack_trace_id);
+  event_target->DispatchEvent(*event);
+  if (debugger)
+    debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/html/portal/portal_post_message_helper.h b/third_party/blink/renderer/core/html/portal/portal_post_message_helper.h
new file mode 100644
index 0000000..8a6a247
--- /dev/null
+++ b/third_party/blink/renderer/core/html/portal/portal_post_message_helper.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 THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_PORTAL_POST_MESSAGE_HELPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_PORTAL_POST_MESSAGE_HELPER_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+namespace blink {
+
+class EventTarget;
+class ExceptionState;
+class ScriptState;
+class ScriptValue;
+class SecurityOrigin;
+class WindowPostMessageOptions;
+struct BlinkTransferableMessage;
+
+class CORE_EXPORT PortalPostMessageHelper {
+  STATIC_ONLY(PortalPostMessageHelper);
+
+ public:
+  static BlinkTransferableMessage CreateMessage(
+      ScriptState* script_state,
+      const ScriptValue& message,
+      const WindowPostMessageOptions* options,
+      ExceptionState& exception_state);
+
+  static void CreateAndDispatchMessageEvent(
+      EventTarget* target,
+      BlinkTransferableMessage message,
+      scoped_refptr<const SecurityOrigin> source_origin,
+      scoped_refptr<const SecurityOrigin> target_origin);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_PORTAL_POST_MESSAGE_HELPER_H_
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css
index 99235bd..04ef8c6f 100644
--- a/third_party/blink/renderer/core/html/resources/html.css
+++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -1008,17 +1008,13 @@
 
 /* states */
 
-video:-internal-spatial-navigation-interest:not(:fullscreen) {
-  outline-offset: -2px;
-}
-
 :-internal-spatial-navigation-interest {
-  outline: auto 5px -webkit-focus-ring-color !important;
-  box-shadow: none !important
+    outline: auto 1px -webkit-focus-ring-color;
+    box-shadow: none !important
 }
 
 :focus {
-    outline: auto 5px -webkit-focus-ring-color
+    outline: auto 1px -webkit-focus-ring-color
 }
 
 html:focus, body:focus {
diff --git a/third_party/blink/renderer/core/html/resources/mac.css b/third_party/blink/renderer/core/html/resources/mac.css
index a99fce9..e575c8e7a 100644
--- a/third_party/blink/renderer/core/html/resources/mac.css
+++ b/third_party/blink/renderer/core/html/resources/mac.css
@@ -30,3 +30,12 @@
     /* Fixed padding provided by ThemeMac::ControlPadding() - 1px for broder */
     padding: 1px 7px 2px;
 }
+
+:-internal-spatial-navigation-interest {
+    outline: auto 5px -webkit-focus-ring-color;
+    box-shadow: none !important
+}
+
+:focus {
+    outline: auto 5px -webkit-focus-ring-color
+}
diff --git a/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc b/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
index cb7f5beb..d395dc21 100644
--- a/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
+++ b/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
@@ -40,7 +40,7 @@
   GetDocument().View()->UpdateAllLifecyclePhases(
       DocumentLifecycle::LifecycleUpdateReason::kTest);
 
-  progress->LazyReattachIfAttached();
+  progress->SetForceReattachLayoutTree();
   GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
   StyleRecalcChange change;
   change = change.ForceRecalcDescendants();
diff --git a/third_party/blink/renderer/core/html/track/html_track_element.cc b/third_party/blink/renderer/core/html/track/html_track_element.cc
index 6b3cbe0..108fa31 100644
--- a/third_party/blink/renderer/core/html/track/html_track_element.cc
+++ b/third_party/blink/renderer/core/html/track/html_track_element.cc
@@ -33,6 +33,7 @@
 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
 #include "third_party/blink/renderer/core/html/track/loadable_text_track.h"
 #include "third_party/blink/renderer/core/html_names.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 
 #define TRACK_LOG_LEVEL 3
 
@@ -217,7 +218,7 @@
   if (loader_)
     loader_->CancelLoad();
 
-  loader_ = TextTrackLoader::Create(*this, GetDocument());
+  loader_ = MakeGarbageCollected<TextTrackLoader>(*this, GetDocument());
   if (!loader_->Load(url_, GetCrossOriginAttributeValue(cors_mode)))
     DidCompleteLoad(kFailure);
 }
diff --git a/third_party/blink/renderer/core/html/track/html_track_element.h b/third_party/blink/renderer/core/html/track/html_track_element.h
index e63090ead..307d0b83 100644
--- a/third_party/blink/renderer/core/html/track/html_track_element.h
+++ b/third_party/blink/renderer/core/html/track/html_track_element.h
@@ -37,7 +37,7 @@
 class LoadableTextTrack;
 
 class HTMLTrackElement final : public HTMLElement,
-                               private TextTrackLoaderClient {
+                               public TextTrackLoaderClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(HTMLTrackElement);
 
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
index 64fb987..7d7cc15 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
@@ -795,7 +795,7 @@
   DCHECK(track() && track()->IsRendered() && IsActive());
 
   if (!display_tree_) {
-    display_tree_ = VTTCueBox::Create(GetDocument());
+    display_tree_ = MakeGarbageCollected<VTTCueBox>(GetDocument());
     display_tree_->AppendChild(cue_background_box_);
   }
 
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
index 9194c39..f4eed44 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
@@ -61,10 +61,6 @@
 
 class VTTCueBox final : public HTMLDivElement {
  public:
-  static VTTCueBox* Create(Document& document) {
-    return MakeGarbageCollected<VTTCueBox>(document);
-  }
-
   explicit VTTCueBox(Document&);
 
   void ApplyCSSProperties(const VTTDisplayParameters&);
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc
index e2362cd9..b8c1512 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc
@@ -27,6 +27,7 @@
 
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 
 namespace blink {
 
@@ -70,16 +71,12 @@
       is_past_node_(0),
       web_vtt_node_type_(node_type) {}
 
-VTTElement* VTTElement::Create(VTTNodeType node_type, Document* document) {
-  return MakeGarbageCollected<VTTElement>(node_type, document);
-}
-
 Element& VTTElement::CloneWithoutAttributesAndChildren(
     Document& factory) const {
-  VTTElement& clone =
-      *Create(static_cast<VTTNodeType>(web_vtt_node_type_), &factory);
-  clone.SetLanguage(language_);
-  return clone;
+  auto* clone = MakeGarbageCollected<VTTElement>(
+      static_cast<VTTNodeType>(web_vtt_node_type_), &factory);
+  clone->SetLanguage(language_);
+  return *clone;
 }
 
 HTMLElement* VTTElement::CreateEquivalentHTMLElement(Document& document) {
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_element.h b/third_party/blink/renderer/core/html/track/vtt/vtt_element.h
index ed66a1c..e9fae7d 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_element.h
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_element.h
@@ -44,8 +44,6 @@
 
 class VTTElement final : public Element {
  public:
-  static VTTElement* Create(const VTTNodeType, Document*);
-  static VTTElement* Create(const QualifiedName&, Document*);
   HTMLElement* CreateEquivalentHTMLElement(Document&);
 
   VTTElement(const QualifiedName&, Document*);
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
index 549899e5..34a8f46 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
@@ -36,6 +36,7 @@
 #include "third_party/blink/renderer/core/html/track/vtt/vtt_element.h"
 #include "third_party/blink/renderer/core/html/track/vtt/vtt_region.h"
 #include "third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/text/segmented_string.h"
@@ -540,7 +541,7 @@
       if (node_type == kVTTNodeTypeRubyText && current_type != kVTTNodeTypeRuby)
         break;
 
-      VTTElement* child = VTTElement::Create(node_type, &document);
+      auto* child = MakeGarbageCollected<VTTElement>(node_type, &document);
       if (!token_.Classes().IsEmpty())
         child->setAttribute(kClassAttr, token_.Classes());
 
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h
index cad46f9..41fd662f 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h
@@ -70,10 +70,6 @@
     kBadCue
   };
 
-  static VTTParser* Create(VTTParserClient* client, Document& document) {
-    return MakeGarbageCollected<VTTParser>(client, document);
-  }
-
   VTTParser(VTTParserClient*, Document&);
   ~VTTParser() = default;
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
index 6fb99485a1..d6ee587 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -737,7 +737,7 @@
 
     // LayoutInline's bounding box includes paddings and borders, excludes
     // margins.
-    border_box = LayoutRect(layout_inline->LinesBoundingBox());
+    border_box = LayoutRect(layout_inline->PhysicalLinesBoundingBox());
     padding_box = LayoutRect(border_box.X() + layout_inline->BorderLeft(),
                              border_box.Y() + layout_inline->BorderTop(),
                              border_box.Width() - layout_inline->BorderLeft() -
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 efc689d..18a5a197 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -210,8 +210,8 @@
   if (target->IsBox())
     return LayoutRect(ToLayoutBoxModelObject(target)->BorderBoundingBox());
   if (target->IsLayoutInline())
-    return ToLayoutInline(target)->LinesBoundingBox();
-  return ToLayoutText(target)->LinesBoundingBox();
+    return ToLayoutInline(target)->PhysicalLinesBoundingBox();
+  return ToLayoutText(target)->PhysicalLinesBoundingBox();
 }
 
 LayoutRect IntersectionGeometry::InitializeRootRect(
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn
index 5b37e80..7d63fa1 100644
--- a/third_party/blink/renderer/core/layout/BUILD.gn
+++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -541,10 +541,17 @@
   }
 
   if (is_android) {
-    sources += [
-      "layout_theme_android.cc",
-      "layout_theme_android.h",
-    ]
+    if (notouch_build) {
+      sources += [
+        "layout_theme_touchless.cc",
+        "layout_theme_touchless.h",
+      ]
+    } else {
+      sources += [
+        "layout_theme_android.cc",
+        "layout_theme_android.h",
+      ]
+    }
   }
 
   if (is_fuchsia) {
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 74dde66..51c0a29 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -1591,12 +1591,11 @@
     LayoutRect overflow_box;
     if (result.GetHitTestRequest().GetType() &
         HitTestRequest::kHitTestVisualOverflow) {
-      overflow_box = VisualOverflowRectIncludingFilters();
+      overflow_box = PhysicalVisualOverflowRectIncludingFilters();
     } else {
       overflow_box = (HasOverflowClip() || ShouldApplyPaintContainment())
                          ? BorderBoxRect()
-                         : VisualOverflowRect();
-      FlipForWritingMode(overflow_box);
+                         : PhysicalVisualOverflowRect();
     }
     LayoutPoint adjusted_location = accumulated_offset + Location();
     overflow_box.MoveBy(adjusted_location);
@@ -1651,8 +1650,7 @@
     LayoutRect bounds_rect;
     if (result.GetHitTestRequest().GetType() &
         HitTestRequest::kHitTestVisualOverflow) {
-      bounds_rect = VisualOverflowRectIncludingFilters();
-      FlipForWritingMode(bounds_rect);
+      bounds_rect = PhysicalVisualOverflowRectIncludingFilters();
     } else {
       bounds_rect = BorderBoxRect();
     }
@@ -1964,7 +1962,7 @@
 }
 
 bool LayoutBox::IntersectsVisibleViewport() const {
-  LayoutRect rect = VisualOverflowRect();
+  LayoutRect rect = PhysicalVisualOverflowRect();
   LayoutView* layout_view = View();
   while (layout_view->GetFrame()->OwnerLayoutObject())
     layout_view = layout_view->GetFrame()->OwnerLayoutObject()->View();
@@ -2685,7 +2683,11 @@
 }
 
 LayoutRect LayoutBox::LocalVisualRectIgnoringVisibility() const {
-  return SelfVisualOverflowRect();
+  // VisualOverflowRect() is in "physical coordinates with flipped blocks
+  // direction", while all "VisualRect"s are in pure physical coordinates.
+  LayoutRect rect = SelfVisualOverflowRect();
+  FlipForWritingMode(rect);
+  return rect;
 }
 
 void LayoutBox::InflateVisualRectForFilterUnderContainer(
@@ -2751,13 +2753,8 @@
       container_offset.MoveBy(
           -table_row_container->PhysicalLocation(ToLayoutBox(container)));
     }
-  } else if (container->IsRuby()) {
-    // TODO(wkorman): Generalize Ruby specialization and/or document more
-    // clearly. See the accompanying specialization in
-    // LayoutInline::mapToVisualRectInAncestorSpaceInternal.
-    container_offset.MoveBy(PhysicalLocation());
   } else {
-    container_offset.MoveBy(Location());
+    container_offset.MoveBy(PhysicalLocation());
   }
 
   const ComputedStyle& style_to_use = StyleRef();
@@ -4260,11 +4257,11 @@
     return LayoutUnit();
 
   LayoutUnit height_result;
-  LayoutRect bounding_box(flow->LinesBoundingBox());
+  auto bounding_box_size = flow->PhysicalLinesBoundingBox().Size();
   if (containing_block->IsHorizontalWritingMode())
-    height_result = bounding_box.Height();
+    height_result = bounding_box_size.Height();
   else
-    height_result = bounding_box.Width();
+    height_result = bounding_box_size.Width();
   height_result -=
       (containing_block->BorderBefore() + containing_block->BorderAfter());
   return height_result;
@@ -5530,9 +5527,8 @@
              : ClientLogicalBottom();
 }
 
-LayoutRect LayoutBox::VisualOverflowRectIncludingFilters() const {
-  LayoutRect bounds_rect = VisualOverflowRect();
-  FlipForWritingMode(bounds_rect);
+LayoutRect LayoutBox::PhysicalVisualOverflowRectIncludingFilters() const {
+  LayoutRect bounds_rect = PhysicalVisualOverflowRect();
   if (!StyleRef().HasFilter())
     return bounds_rect;
   FloatRect float_rect = Layer()->MapRectForFilter(FloatRect(bounds_rect));
@@ -6269,7 +6265,7 @@
 }
 
 LayoutRect LayoutBox::DebugRect() const {
-  return FrameRect();
+  return LayoutRect(PhysicalLocation(), Size());
 }
 
 bool LayoutBox::ComputeShouldClipOverflow() const {
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index 7616f30..d3f157ce 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -519,7 +519,7 @@
 
   // Returns the visual overflow rect, expanded to the area affected by any
   // filters that paint outside of the box, in physical coordinates.
-  LayoutRect VisualOverflowRectIncludingFilters() const;
+  LayoutRect PhysicalVisualOverflowRectIncludingFilters() const;
 
   // These methods don't mean the box *actually* has top/left overflow. They
   // mean that *if* the box overflows, it will overflow to the top/left rather
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
index 7efadc2..4f182e4 100644
--- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -897,14 +897,16 @@
   constraints.scroll_container_relative_containing_block_rect =
       FloatRect(scroll_container_relative_containing_block_rect);
 
-  FloatRect sticky_box_rect =
-      IsLayoutInline() ? FloatRect(ToLayoutInline(this)->LinesBoundingBox())
-                       : FloatRect(ToLayoutBox(this)->FrameRect());
-
-  FloatRect flipped_sticky_box_rect = sticky_box_rect;
-  containing_block->FlipForWritingMode(flipped_sticky_box_rect);
+  FloatRect sticky_box_rect;
+  if (IsLayoutInline()) {
+    sticky_box_rect =
+        FloatRect(ToLayoutInline(this)->PhysicalLinesBoundingBox());
+  } else {
+    sticky_box_rect = FloatRect(ToLayoutBox(this)->FrameRect());
+    containing_block->FlipForWritingMode(sticky_box_rect);
+  }
   FloatPoint sticky_location =
-      flipped_sticky_box_rect.Location() + skipped_containers_offset;
+      sticky_box_rect.Location() + skipped_containers_offset;
 
   // The scrollContainerRelativePaddingBoxRect's position is the padding box so
   // we need to remove the border when finding the position of the sticky box
@@ -917,7 +919,7 @@
   constraints.scroll_container_relative_sticky_box_rect =
       FloatRect(scroll_container_relative_padding_box_rect.Location() +
                     ToFloatSize(sticky_location),
-                flipped_sticky_box_rect.Size());
+                sticky_box_rect.Size());
 
   // To correctly compute the offsets, the constraints need to know about any
   // nested position:sticky elements between themselves and their
diff --git a/third_party/blink/renderer/core/layout/layout_br.h b/third_party/blink/renderer/core/layout/layout_br.h
index 0c11848..de9a9b93 100644
--- a/third_party/blink/renderer/core/layout/layout_br.h
+++ b/third_party/blink/renderer/core/layout/layout_br.h
@@ -36,7 +36,7 @@
 
   // Although line breaks contain no actual text, if we're selected we need
   // to return a rect that includes space to illustrate a newline.
-  using LayoutText::LocalSelectionRect;
+  using LayoutText::LocalSelectionVisualRect;
 
   float Width(unsigned /* from */,
               unsigned /* len */,
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc
index 43f9f092..14d91089 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -1245,7 +1245,7 @@
 
 }  // unnamed namespace
 
-LayoutRect LayoutInline::LinesBoundingBox() const {
+LayoutRect LayoutInline::PhysicalLinesBoundingBox() const {
   if (IsInLayoutNGInlineFormattingContext()) {
     const NGPhysicalBoxFragment* box_fragment =
         ContainingBlockFlowFragmentOf(*this);
@@ -1257,8 +1257,6 @@
     for (const auto& child : children)
       bounding_box.UniteIfNonZero(child.RectInContainerBox());
     LayoutRect rect = bounding_box.ToLayoutRect();
-    if (UNLIKELY(HasFlippedBlocksWritingMode()))
-      ContainingBlock()->FlipForWritingMode(rect);
     return rect;
   }
 
@@ -1267,6 +1265,8 @@
     FloatRect float_result;
     LinesBoundingBoxGeneratorContext context(float_result);
     GenerateCulledLineBoxRects(context, this);
+    if (UNLIKELY(HasFlippedBlocksWritingMode()))
+      ContainingBlock()->FlipForWritingMode(float_result);
     return EnclosingLayoutRect(float_result);
   }
 
@@ -1302,6 +1302,8 @@
     result = LayoutRect(x, y, width, height);
   }
 
+  if (UNLIKELY(HasFlippedBlocksWritingMode()))
+    ContainingBlock()->FlipForWritingMode(result);
   return result;
 }
 
@@ -1464,16 +1466,20 @@
 
 LayoutRect LayoutInline::LocalVisualRectIgnoringVisibility() const {
   if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
-    LayoutRect visual_rect;
-    if (NGPaintFragment::FlippedLocalVisualRectFor(this, &visual_rect))
-      return visual_rect;
+    if (const auto& visual_rect = NGPaintFragment::LocalVisualRectFor(*this))
+      return *visual_rect;
   }
 
   // If we don't create line boxes, we don't have any invalidations to do.
   if (!AlwaysCreateLineBoxes())
     return LayoutRect();
 
-  return VisualOverflowRect();
+  // VisualOverflowRect() is in "physical coordinates with flipped blocks
+  // direction", while all "VisualRect"s are in pure physical coordinates.
+  auto rect = VisualOverflowRect();
+  if (UNLIKELY(HasFlippedBlocksWritingMode()))
+    ContainingBlock()->FlipForWritingMode(rect);
+  return rect;
 }
 
 LayoutRect LayoutInline::VisualOverflowRect() const {
@@ -1556,13 +1562,6 @@
                                                 *this, visual_rect_flags))
     return false;
 
-  // TODO(wkorman): Generalize Ruby specialization and/or document more clearly.
-  if (container_box && !IsRuby()) {
-    transform_state.Flatten();
-    LayoutRect rect(transform_state.LastPlanarQuad().BoundingBox());
-    container_box->FlipForWritingMode(rect);
-    transform_state.SetQuad(FloatQuad(FloatRect(rect)));
-  }
   return container->MapToVisualRectInAncestorSpaceInternal(
       ancestor, transform_state, visual_rect_flags);
 }
@@ -1847,7 +1846,7 @@
   AnnotatedRegionValue region;
   region.draggable =
       StyleRef().DraggableRegionMode() == EDraggableRegionMode::kDrag;
-  region.bounds = LayoutRect(LinesBoundingBox());
+  region.bounds = LayoutRect(PhysicalLinesBoundingBox());
 
   LayoutObject* container = ContainingBlock();
   if (!container)
@@ -1894,7 +1893,7 @@
 }
 
 LayoutRect LayoutInline::DebugRect() const {
-  return LayoutRect(EnclosingIntRect(LinesBoundingBox()));
+  return LayoutRect(EnclosingIntRect(PhysicalLinesBoundingBox()));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_inline.h b/third_party/blink/renderer/core/layout/layout_inline.h
index d11eab6..f7cdddc 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.h
+++ b/third_party/blink/renderer/core/layout/layout_inline.h
@@ -156,7 +156,7 @@
                      const LayoutPoint& accumulated_offset) const final;
   FloatRect LocalBoundingBoxRectForAccessibility() const final;
 
-  LayoutRect LinesBoundingBox() const;
+  LayoutRect PhysicalLinesBoundingBox() const;
   LayoutRect VisualOverflowRect() const final;
   LayoutRect ReferenceBoxForClipPath() const;
 
@@ -340,15 +340,20 @@
 
   LayoutUnit OffsetLeft(const Element*) const final;
   LayoutUnit OffsetTop(const Element*) const final;
-  LayoutUnit OffsetWidth() const final { return LinesBoundingBox().Width(); }
-  LayoutUnit OffsetHeight() const final { return LinesBoundingBox().Height(); }
+  LayoutUnit OffsetWidth() const final {
+    return PhysicalLinesBoundingBox().Width();
+  }
+  LayoutUnit OffsetHeight() const final {
+    return PhysicalLinesBoundingBox().Height();
+  }
 
   LayoutRect VisualRectInDocument(
       VisualRectFlags = kDefaultVisualRectFlags) const override;
 
-  // This method differs from visualOverflowRect in that it doesn't include the
-  // rects for culled inline boxes, which aren't necessary for paint
-  // invalidation.
+  // This method differs from VisualOverflowRect() in that
+  // 1. it doesn't include the rects for culled inline boxes, which aren't
+  //    necessary for paint invalidation;
+  // 2. it is in physical coordinates.
   LayoutRect LocalVisualRectIgnoringVisibility() const override;
 
   bool MapToVisualRectInAncestorSpaceInternal(
@@ -359,7 +364,7 @@
   PositionWithAffinity PositionForPoint(const LayoutPoint&) const final;
 
   IntRect BorderBoundingBox() const final {
-    IntRect bounding_box = EnclosingIntRect(LinesBoundingBox());
+    IntRect bounding_box = EnclosingIntRect(PhysicalLinesBoundingBox());
     return IntRect(0, 0, bounding_box.Width(), bounding_box.Height());
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_inline_test.cc b/third_party/blink/renderer/core/layout/layout_inline_test.cc
index a05833e..9c6ffc3 100644
--- a/third_party/blink/renderer/core/layout/layout_inline_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_inline_test.cc
@@ -30,35 +30,35 @@
 
 INSTANTIATE_TEST_SUITE_P(All, ParameterizedLayoutInlineTest, testing::Bool());
 
-TEST_P(ParameterizedLayoutInlineTest, LinesBoundingBox) {
+TEST_P(ParameterizedLayoutInlineTest, PhysicalLinesBoundingBox) {
   LoadAhem();
-  SetBodyInnerHTML(
-      "<style>"
-      "html { font-family: Ahem; font-size: 13px; }"
-      // LayoutNG requires box decorations at this moment. crbug.com/789390
-      "span { background-color: yellow; }"
-      ".vertical { writing-mode: vertical-rl; }"
-      "</style>"
-      "<p><span id=ltr1>abc<br>xyz</span></p>"
-      "<p><span id=ltr2>12 345 6789</span></p>"
-      "<p dir=rtl><span id=rtl1>abc<br>xyz</span></p>"
-      "<p dir=rtl><span id=rtl2>12 345 6789</span></p>"
-      "<p class=vertical><span id=vertical>abc<br>xyz</span></p>");
-  EXPECT_EQ(
-      LayoutRect(LayoutPoint(0, 0), LayoutSize(39, 26)),
-      ToLayoutInline(GetLayoutObjectByElementId("ltr1"))->LinesBoundingBox());
-  EXPECT_EQ(
-      LayoutRect(LayoutPoint(0, 0), LayoutSize(143, 13)),
-      ToLayoutInline(GetLayoutObjectByElementId("ltr2"))->LinesBoundingBox());
-  EXPECT_EQ(
-      LayoutRect(LayoutPoint(745, 0), LayoutSize(39, 26)),
-      ToLayoutInline(GetLayoutObjectByElementId("rtl1"))->LinesBoundingBox());
-  EXPECT_EQ(
-      LayoutRect(LayoutPoint(641, 0), LayoutSize(143, 13)),
-      ToLayoutInline(GetLayoutObjectByElementId("rtl2"))->LinesBoundingBox());
-  EXPECT_EQ(LayoutRect(LayoutPoint(0, 0), LayoutSize(26, 39)),
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      html { font-family: Ahem; font-size: 10px; line-height: 10px; }
+      p { width: 300px; height: 100px; }
+      .vertical { writing-mode: vertical-rl; }
+    </style>
+    <p><span id=ltr1>abc<br>xyz</span></p>
+    <p><span id=ltr2>12 345 6789</span></p>
+    <p dir=rtl><span id=rtl1>abc<br>xyz</span></p>
+    <p dir=rtl><span id=rtl2>12 345 6789</span></p>
+    <p class=vertical><span id=vertical>abc<br>xyz</span></p>
+  )HTML");
+  EXPECT_EQ(LayoutRect(0, 0, 30, 20),
+            ToLayoutInline(GetLayoutObjectByElementId("ltr1"))
+                ->PhysicalLinesBoundingBox());
+  EXPECT_EQ(LayoutRect(0, 0, 110, 10),
+            ToLayoutInline(GetLayoutObjectByElementId("ltr2"))
+                ->PhysicalLinesBoundingBox());
+  EXPECT_EQ(LayoutRect(270, 0, 30, 20),
+            ToLayoutInline(GetLayoutObjectByElementId("rtl1"))
+                ->PhysicalLinesBoundingBox());
+  EXPECT_EQ(LayoutRect(190, 0, 110, 10),
+            ToLayoutInline(GetLayoutObjectByElementId("rtl2"))
+                ->PhysicalLinesBoundingBox());
+  EXPECT_EQ(LayoutRect(280, 0, 20, 30),
             ToLayoutInline(GetLayoutObjectByElementId("vertical"))
-                ->LinesBoundingBox());
+                ->PhysicalLinesBoundingBox());
 }
 
 TEST_F(LayoutInlineTest, SimpleContinuation) {
@@ -465,4 +465,72 @@
                 ->AbsoluteBoundingBoxRectHandlingEmptyInline());
 }
 
+TEST_P(ParameterizedLayoutInlineTest, AddAnnotatedRegions) {
+  LoadAhem();
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      body {
+        margin: 0;
+        font: 10px/10px Ahem;
+      }
+    </style>
+    <div style="width: 600px; height: 400px">
+      A<br>B
+      <span id="target1" style="-webkit-app-region: drag">CDE<br>FGH</span>
+      <span id="target2" style="-webkit-app-region: no-drag">IJK<br>LMN</span>
+      <span id="target3">OPQ<br>RST</span>
+    </div>
+  )HTML");
+
+  Vector<AnnotatedRegionValue> regions1;
+  GetLayoutObjectByElementId("target1")->AddAnnotatedRegions(regions1);
+  ASSERT_EQ(1u, regions1.size());
+  EXPECT_EQ(LayoutRect(0, 10, 50, 20), regions1[0].bounds);
+  EXPECT_TRUE(regions1[0].draggable);
+
+  Vector<AnnotatedRegionValue> regions2;
+  GetLayoutObjectByElementId("target2")->AddAnnotatedRegions(regions2);
+  ASSERT_EQ(1u, regions2.size());
+  EXPECT_EQ(LayoutRect(0, 20, 70, 20), regions2[0].bounds);
+  EXPECT_FALSE(regions2[0].draggable);
+
+  Vector<AnnotatedRegionValue> regions3;
+  GetLayoutObjectByElementId("target3")->AddAnnotatedRegions(regions3);
+  EXPECT_TRUE(regions3.IsEmpty());
+}
+
+TEST_P(ParameterizedLayoutInlineTest, AddAnnotatedRegionsVerticalRL) {
+  LoadAhem();
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      body {
+        margin: 0;
+        font: 10px/10px Ahem;
+      }
+    </style>
+    <div style="width: 600px; height: 400px; writing-mode: vertical-rl">
+      A<br>B
+      <span id="target1" style="-webkit-app-region: drag">CDE<br>FGH</span>
+      <span id="target2" style="-webkit-app-region: no-drag">IJK<br>LMN</span>
+      <span id="target3">OPQ<br>RST</span>
+    </div>
+  )HTML");
+
+  Vector<AnnotatedRegionValue> regions1;
+  GetLayoutObjectByElementId("target1")->AddAnnotatedRegions(regions1);
+  ASSERT_EQ(1u, regions1.size());
+  EXPECT_EQ(LayoutRect(570, 0, 20, 50), regions1[0].bounds);
+  EXPECT_TRUE(regions1[0].draggable);
+
+  Vector<AnnotatedRegionValue> regions2;
+  GetLayoutObjectByElementId("target2")->AddAnnotatedRegions(regions2);
+  ASSERT_EQ(1u, regions2.size());
+  EXPECT_EQ(LayoutRect(560, 0, 20, 70), regions2[0].bounds);
+  EXPECT_FALSE(regions2[0].draggable);
+
+  Vector<AnnotatedRegionValue> regions3;
+  GetLayoutObjectByElementId("target3")->AddAnnotatedRegions(regions3);
+  EXPECT_TRUE(regions3.IsEmpty());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 0969debd..f226bab 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1531,7 +1531,7 @@
 }
 
 LayoutRect LayoutObject::AbsoluteSelectionRect() const {
-  LayoutRect selection_rect = LocalSelectionRect();
+  LayoutRect selection_rect = LocalSelectionVisualRect();
   if (!selection_rect.IsEmpty())
     MapToVisualRectInAncestorSpace(View(), selection_rect);
 
@@ -1664,25 +1664,14 @@
 
   if (LayoutObject* parent = Parent()) {
     if (parent->IsBox()) {
-      LayoutBox* parent_box = ToLayoutBox(parent);
-
-      // Never flip for SVG as it handles writing modes itself.
-      if (!IsSVG()) {
-        transform_state.Flatten();
-        LayoutRect rect(transform_state.LastPlanarQuad().BoundingBox());
-        parent_box->FlipForWritingMode(rect);
-        transform_state.SetQuad(FloatQuad(FloatRect(rect)));
-      }
-
       bool preserve3d = parent->StyleRef().Preserves3D() && !parent->IsText();
-
       TransformState::TransformAccumulation accumulation =
           preserve3d ? TransformState::kAccumulateTransform
                      : TransformState::kFlattenTransform;
 
       if (parent != ancestor &&
-          !parent_box->MapContentsRectToBoxSpace(transform_state, accumulation,
-                                                 *this, visual_rect_flags))
+          !ToLayoutBox(parent)->MapContentsRectToBoxSpace(
+              transform_state, accumulation, *this, visual_rect_flags))
         return false;
     }
     return parent->MapToVisualRectInAncestorSpaceInternal(
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 1dc9b93e..349b8d4 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1657,10 +1657,10 @@
       VisualRectFlags = kDefaultVisualRectFlags) const;
 
   // Returns the rect that should have raster invalidated whenever this object
-  // changes. The rect is in the object's local coordinate space. This is for
-  // non-SVG objects and LayoutSVGRoot only. SVG objects (except LayoutSVGRoot)
-  // should use VisualRectInLocalSVGCoordinates() and map with SVG transforms
-  // instead.
+  // changes. The rect is in the object's local physical coordinate space.
+  // This is for non-SVG objects and LayoutSVGRoot only. SVG objects (except
+  // LayoutSVGRoot) should use VisualRectInLocalSVGCoordinates() and map with
+  // SVG transforms instead.
   LayoutRect LocalVisualRect() const {
     if (StyleRef().Visibility() != EVisibility::kVisible &&
         VisualRectRespectsVisibility())
@@ -1668,11 +1668,11 @@
     return LocalVisualRectIgnoringVisibility();
   }
 
-  // Given a rect in the object's coordinate space, mutates the rect into one
-  // representing the size of its visual painted output as if |ancestor| was the
-  // root of the page: the rect is modified by any intervening clips, transforms
-  // and scrolls between |this| and |ancestor| (not inclusive of |ancestor|),
-  // but not any above |ancestor|.
+  // Given a rect in the object's physical coordinate space, mutates the rect
+  // into one representing the size of its visual painted output as if
+  // |ancestor| was the root of the page: the rect is modified by any
+  // intervening clips, transforms and scrolls between |this| and |ancestor|
+  // (not inclusive of |ancestor|), but not any above |ancestor|.
   // The output is in the physical, painted coordinate pixel space of
   // |ancestor|.
   // Overflow clipping, CSS clipping and scrolling is *not* applied for
@@ -1683,10 +1683,10 @@
   // the rect to the main frame's space which includes the root view's scroll
   // and clip. This is even true if the main frame is remote.
   //
-  // If visualRectFlags has the EdgeInclusive bit set, clipping operations will
+  // If VisualRectFlags has the kEdgeInclusive bit set, clipping operations will
   // use LayoutRect::InclusiveIntersect, and the return value of
   // InclusiveIntersect will be propagated to the return value of this method.
-  // Otherwise, clipping operations will use LayoutRect::intersect, and the
+  // Otherwise, clipping operations will use LayoutRect::Intersect, and the
   // return value will be true only if the clipped rect has non-zero area.
   // See the documentation for LayoutRect::InclusiveIntersect for more
   // information.
@@ -1736,8 +1736,8 @@
 
   // A single rectangle that encompasses all of the selected objects within this
   // object. Used to determine the tightest possible bounding box for the
-  // selection. The rect returned is in the object's local coordinate space.
-  virtual LayoutRect LocalSelectionRect() const { return LayoutRect(); }
+  // selection. The rect is in the object's local physical coordinate space.
+  virtual LayoutRect LocalSelectionVisualRect() const { return LayoutRect(); }
 
   LayoutRect AbsoluteSelectionRect() const;
 
@@ -2455,6 +2455,7 @@
     bitfields_.SetPreviousOutlineMayBeAffectedByDescendants(b);
   }
 
+  // See LocalVisualRect().
   virtual bool VisualRectRespectsVisibility() const { return true; }
   virtual LayoutRect LocalVisualRectIgnoringVisibility() const;
 
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc
index 7edc19c..8eac589 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -160,11 +160,17 @@
 
 void LayoutReplaced::ComputeIntrinsicSizingInfoForReplacedContent(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
-  // TODO(crbug.com/953925): How should we size display-locked replaced content?
   if (ShouldApplySizeContainment()) {
     intrinsic_sizing_info.size = FloatSize();
     return;
   }
+  if (DisplayLockInducesSizeContainment()) {
+    auto* context = GetDisplayLockContext();
+    intrinsic_sizing_info.size =
+        FloatSize(context->GetLockedContentLogicalWidth(),
+                  context->GetLockedContentLogicalHeight());
+    return;
+  }
 
   ComputeIntrinsicSizingInfo(intrinsic_sizing_info);
 
@@ -981,7 +987,7 @@
   return LayoutBox::PositionForPoint(point);
 }
 
-LayoutRect LayoutReplaced::LocalSelectionRect() const {
+LayoutRect LayoutReplaced::LocalSelectionVisualRect() const {
   if (GetSelectionState() == SelectionState::kNone ||
       GetSelectionState() == SelectionState::kContain) {
     return LayoutRect();
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.h b/third_party/blink/renderer/core/layout/layout_replaced.h
index 2682400..6432c6fc 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.h
+++ b/third_party/blink/renderer/core/layout/layout_replaced.h
@@ -80,7 +80,8 @@
   bool CanHaveChildren() const override { return false; }
   virtual void PaintReplaced(const PaintInfo&,
                              const LayoutPoint& paint_offset) const {}
-  LayoutRect LocalSelectionRect() const final;
+
+  LayoutRect LocalSelectionVisualRect() const final;
 
   bool HasObjectFit() const {
     return StyleRef().GetObjectFit() !=
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.cc b/third_party/blink/renderer/core/layout/layout_table_cell.cc
index 2ec25ac..882475fe 100644
--- a/third_party/blink/renderer/core/layout/layout_table_cell.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_cell.cc
@@ -381,7 +381,7 @@
   unsigned top = CollapsedBorderHalfTop(true);
   unsigned bottom = CollapsedBorderHalfBottom(true);
 
-  // TODO(wangxianzhu): The following looks incorrect for vertical direction.
+  // TODO(layout-ng): The following looks incorrect for vertical direction.
   // This cell's borders may be lengthened to match the widths of orthogonal
   // borders of adjacent cells. Expand visual overflow to cover the lengthened
   // parts.
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index f6e4dd0..481f6af 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -1988,7 +1988,7 @@
   return w;
 }
 
-LayoutRect LayoutText::LinesBoundingBox() const {
+LayoutRect LayoutText::PhysicalLinesBoundingBox() const {
   if (const NGPhysicalBoxFragment* box_fragment =
           ContainingBlockFlowFragment()) {
     PhysicalRect bounding_box;
@@ -1996,10 +1996,7 @@
         NGInlineFragmentTraversal::SelfFragmentsOf(*box_fragment, this);
     for (const auto& child : children)
       bounding_box.UniteIfNonZero(child.RectInContainerBox());
-    LayoutRect rect = bounding_box.ToLayoutRect();
-    if (HasFlippedBlocksWritingMode())
-      ContainingBlock()->FlipForWritingMode(rect);
-    return rect;
+    return bounding_box.ToLayoutRect();
   }
 
   LayoutRect result;
@@ -2028,15 +2025,17 @@
     result = EnclosingLayoutRect(FloatRect(x, y, width, height));
   }
 
+  if (UNLIKELY(HasFlippedBlocksWritingMode()))
+    ContainingBlock()->FlipForWritingMode(result);
   return result;
 }
 
 LayoutRect LayoutText::VisualOverflowRect() const {
-  if (IsInLayoutNGInlineFormattingContext()) {
-    LayoutRect rect;
-    if (NGPaintFragment::FlippedLocalVisualRectFor(this, &rect))
-      return rect;
-    NOTREACHED();
+  if (base::Optional<LayoutRect> rect =
+          NGPaintFragment::LocalVisualRectFor(*this)) {
+    if (UNLIKELY(HasFlippedBlocksWritingMode()))
+      ContainingBlock()->FlipForWritingMode(*rect);
+    return *rect;
   }
 
   if (!FirstTextBox())
@@ -2084,26 +2083,20 @@
 }
 
 LayoutRect LayoutText::LocalVisualRectIgnoringVisibility() const {
-  if (IsInLayoutNGInlineFormattingContext()) {
-    LayoutRect rect;
-    if (NGPaintFragment::FlippedLocalVisualRectFor(this, &rect)) {
-      if (!IsSelected())
-        return rect;
-      return UnionRect(rect, LocalSelectionRect());
-    }
-    NOTREACHED();
-  }
-  return UnionRect(VisualOverflowRect(), LocalSelectionRect());
+  if (const auto& rect = NGPaintFragment::LocalVisualRectFor(*this))
+    return UnionRect(*rect, LocalSelectionVisualRect());
+
+  auto rect = VisualOverflowRect();
+  if (UNLIKELY(HasFlippedBlocksWritingMode()))
+    ContainingBlock()->FlipForWritingMode(rect);
+  return UnionRect(rect, LocalSelectionVisualRect());
 }
 
-LayoutRect LayoutText::LocalSelectionRect() const {
+LayoutRect LayoutText::LocalSelectionVisualRect() const {
   DCHECK(!NeedsLayout());
 
   if (!IsSelected())
     return LayoutRect();
-  LayoutBlock* cb = ContainingBlock();
-  if (!cb)
-    return LayoutRect();
 
   const FrameSelection& frame_selection = GetFrame()->Selection();
   const auto fragments = NGPaintFragment::InlineFragmentsFor(this);
@@ -2119,15 +2112,6 @@
       fragment_rect.offset += fragment->InlineOffsetToContainerBox();
       rect.Unite(fragment_rect.ToLayoutRect());
     }
-
-    if (!HasFlippedBlocksWritingMode())
-      return rect;
-    // Since legacy requires LocalSelectionRect return flipped block direction,
-    // we need to convert physical coordinates into physical coordinates in
-    // flipped block direction.
-    NGPaintFragment* container = NGPaintFragment::GetForInlineContainer(this);
-    DCHECK(container);
-    ToLayoutBox(container->GetLayoutObject())->FlipForWritingMode(rect);
     return rect;
   }
 
@@ -2142,6 +2126,8 @@
     rect.Unite(LayoutRect(EllipsisRectForBox(box, start_pos, end_pos)));
   }
 
+  if (UNLIKELY(HasFlippedBlocksWritingMode()))
+    ContainingBlock()->FlipForWritingMode(rect);
   return rect;
 }
 
@@ -2462,7 +2448,7 @@
 }
 
 LayoutRect LayoutText::DebugRect() const {
-  return LayoutRect(EnclosingIntRect(LinesBoundingBox()));
+  return LayoutRect(EnclosingIntRect(PhysicalLinesBoundingBox()));
 }
 
 NodeHolder LayoutText::EnsureNodeHolder() {
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h
index d066db0..3587282 100644
--- a/third_party/blink/renderer/core/layout/layout_text.h
+++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -186,9 +186,10 @@
                          bool& strip_front_spaces,
                          TextDirection);
 
-  virtual LayoutRect LinesBoundingBox() const;
+  virtual LayoutRect PhysicalLinesBoundingBox() const;
 
-  // Returns the bounding box of visual overflow rects of all line boxes.
+  // Returns the bounding box of visual overflow rects of all line boxes,
+  // in containing block's physical coordinates with flipped blocks direction.
   LayoutRect VisualOverflowRect() const;
 
   LayoutPoint FirstLineBoxTopLeft() const;
@@ -203,7 +204,7 @@
 
   virtual void TransformText();
 
-  LayoutRect LocalSelectionRect() const final;
+  LayoutRect LocalSelectionVisualRect() const final;
   LayoutRect LocalCaretRect(
       const InlineBox*,
       int caret_offset,
diff --git a/third_party/blink/renderer/core/layout/layout_text_test.cc b/third_party/blink/renderer/core/layout/layout_text_test.cc
index 62d8fb3..89a85bd 100644
--- a/third_party/blink/renderer/core/layout/layout_text_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_test.cc
@@ -64,7 +64,7 @@
     const Node* target = GetDocument().getElementById("target");
     const LayoutObject* layout_object =
         target ? target->GetLayoutObject() : FindFirstLayoutText();
-    return layout_object->LocalSelectionRect();
+    return layout_object->LocalSelectionVisualRect();
   }
 };
 
@@ -587,7 +587,7 @@
                                           IntRect(110, 200, 10, 20)));
 }
 
-TEST_P(ParameterizedLayoutTextTest, LinesBoundingBox) {
+TEST_P(ParameterizedLayoutTextTest, PhysicalLinesBoundingBox) {
   LoadAhem();
   SetBasicBody(
       "<style>"
@@ -620,15 +620,52 @@
   const Element& div = *GetDocument().getElementById("div");
   const Element& one = *GetDocument().getElementById("one");
   const Element& two = *GetDocument().getElementById("two");
-  EXPECT_EQ(
-      LayoutRect(LayoutPoint(3, 6), LayoutSize(52, 13)),
-      ToLayoutText(div.firstChild()->GetLayoutObject())->LinesBoundingBox());
-  EXPECT_EQ(
-      LayoutRect(LayoutPoint(55, 6), LayoutSize(39, 13)),
-      ToLayoutText(one.firstChild()->GetLayoutObject())->LinesBoundingBox());
-  EXPECT_EQ(
-      LayoutRect(LayoutPoint(28, 25), LayoutSize(39, 13)),
-      ToLayoutText(two.firstChild()->GetLayoutObject())->LinesBoundingBox());
+  EXPECT_EQ(LayoutRect(LayoutPoint(3, 6), LayoutSize(52, 13)),
+            ToLayoutText(div.firstChild()->GetLayoutObject())
+                ->PhysicalLinesBoundingBox());
+  EXPECT_EQ(LayoutRect(LayoutPoint(55, 6), LayoutSize(39, 13)),
+            ToLayoutText(one.firstChild()->GetLayoutObject())
+                ->PhysicalLinesBoundingBox());
+  EXPECT_EQ(LayoutRect(LayoutPoint(28, 25), LayoutSize(39, 13)),
+            ToLayoutText(two.firstChild()->GetLayoutObject())
+                ->PhysicalLinesBoundingBox());
+}
+
+TEST_P(ParameterizedLayoutTextTest, PhysicalLinesBoundingBoxVerticalRL) {
+  LoadAhem();
+  SetBasicBody(R"HTML(
+    <style>
+    div {
+      font-family:Ahem;
+      font-size: 13px;
+      line-height: 19px;
+      padding: 3px;
+      writing-mode: vertical-rl;
+    }
+    </style>
+    <div id=div>
+      012
+      <span id=one>345</span>
+      <br>
+      <span style='padding: 20px'>
+        <span id=two style='padding: 5px'>678</span>
+      </span>
+    </div>
+  )HTML");
+  // Similar to the previous test, with logical coordinates converted to
+  // physical coordinates.
+  const Element& div = *GetDocument().getElementById("div");
+  const Element& one = *GetDocument().getElementById("one");
+  const Element& two = *GetDocument().getElementById("two");
+  EXPECT_EQ(LayoutRect(LayoutPoint(25, 3), LayoutSize(13, 52)),
+            ToLayoutText(div.firstChild()->GetLayoutObject())
+                ->PhysicalLinesBoundingBox());
+  EXPECT_EQ(LayoutRect(LayoutPoint(25, 55), LayoutSize(13, 39)),
+            ToLayoutText(one.firstChild()->GetLayoutObject())
+                ->PhysicalLinesBoundingBox());
+  EXPECT_EQ(LayoutRect(LayoutPoint(6, 28), LayoutSize(13, 39)),
+            ToLayoutText(two.firstChild()->GetLayoutObject())
+                ->PhysicalLinesBoundingBox());
 }
 
 TEST_P(ParameterizedLayoutTextTest, QuadsBasic) {
@@ -721,7 +758,7 @@
       GetSelectionRectFor("<div style='writing-mode: vertical-lr; height: 2em'>"
                           "f^oo ba|r baz</div>"));
   EXPECT_EQ(
-      LayoutRect(0, 0, 20, 40),
+      LayoutRect(10, 0, 20, 40),
       GetSelectionRectFor("<div style='writing-mode: vertical-rl; height: 2em'>"
                           "f^oo ba|r baz</div>"));
 }
@@ -734,8 +771,8 @@
             GetSelectionRectFor(
                 "<div style='writing-mode: vertical-lr; height: 2em' dir=rtl>"
                 "f^oo ba|r baz</div>"));
-  EXPECT_EQ(LayoutNGEnabled() ? LayoutRect(0, -10, 20, 30)
-                              : LayoutRect(0, -10, 20, 40),
+  EXPECT_EQ(LayoutNGEnabled() ? LayoutRect(10, -10, 20, 30)
+                              : LayoutRect(10, -10, 20, 40),
             GetSelectionRectFor(
                 "<div style='writing-mode: vertical-rl; height: 2em' dir=rtl>"
                 "f^oo ba|r baz</div>"));
diff --git a/third_party/blink/renderer/core/layout/layout_theme.cc b/third_party/blink/renderer/core/layout/layout_theme.cc
index 682bc4dc..50db8d9b 100644
--- a/third_party/blink/renderer/core/layout/layout_theme.cc
+++ b/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -652,19 +652,7 @@
 }
 
 bool LayoutTheme::IsFocusRingOutset() const {
-  return is_focus_ring_outset_;
-}
-
-void LayoutTheme::SetIsFocusRingOutset(bool is_outset) {
-  is_focus_ring_outset_ = is_outset;
-}
-
-float LayoutTheme::MinimumStrokeWidthForFocusRing() const {
-  return minimum_width_for_focus_ring_;
-}
-
-void LayoutTheme::SetMinimumStrokeWidthForFocusRing(float stroke_width) {
-  minimum_width_for_focus_ring_ = stroke_width;
+  return false;
 }
 
 Color LayoutTheme::FocusRingColor() const {
diff --git a/third_party/blink/renderer/core/layout/layout_theme.h b/third_party/blink/renderer/core/layout/layout_theme.h
index 926cb549..6a43e47 100644
--- a/third_party/blink/renderer/core/layout/layout_theme.h
+++ b/third_party/blink/renderer/core/layout/layout_theme.h
@@ -158,10 +158,7 @@
   Color PlatformTextSearchHighlightColor(bool active_match) const;
   Color PlatformTextSearchColor(bool active_match) const;
 
-  bool IsFocusRingOutset() const;
-  void SetIsFocusRingOutset(bool is_outset);
-  float MinimumStrokeWidthForFocusRing() const;
-  void SetMinimumStrokeWidthForFocusRing(float stroke_width);
+  virtual bool IsFocusRingOutset() const;
   Color FocusRingColor() const;
   virtual Color PlatformFocusRingColor() const { return Color(0, 0, 0); }
   void SetCustomFocusRingColor(const Color&);
@@ -351,8 +348,6 @@
   // implementation to hand back the appropriate platform theme.
   static LayoutTheme& NativeTheme();
 
-  bool is_focus_ring_outset_ = false;
-  float minimum_width_for_focus_ring_ = 1.0f;
   Color custom_focus_ring_color_;
   bool has_custom_focus_ring_color_;
   TimeDelta caret_blink_interval_ = TimeDelta::FromMilliseconds(500);
diff --git a/third_party/blink/renderer/core/layout/layout_theme_touchless.cc b/third_party/blink/renderer/core/layout/layout_theme_touchless.cc
new file mode 100644
index 0000000..9be8371
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/layout_theme_touchless.cc
@@ -0,0 +1,25 @@
+// 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/layout_theme_touchless.h"
+
+namespace blink {
+
+scoped_refptr<LayoutTheme> LayoutThemeTouchless::Create() {
+  return base::AdoptRef(new LayoutThemeTouchless());
+}
+
+LayoutTheme& LayoutTheme::NativeTheme() {
+  DEFINE_STATIC_REF(LayoutTheme, layout_theme,
+                    (LayoutThemeTouchless::Create()));
+  return *layout_theme;
+}
+
+LayoutThemeTouchless::~LayoutThemeTouchless() {}
+
+bool LayoutThemeTouchless::IsFocusRingOutset() const {
+  return true;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_theme_touchless.h b/third_party/blink/renderer/core/layout/layout_theme_touchless.h
new file mode 100644
index 0000000..ff63ccc
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/layout_theme_touchless.h
@@ -0,0 +1,25 @@
+// 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_LAYOUT_THEME_TOUCHLESS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_THEME_TOUCHLESS_H_
+
+#include "third_party/blink/renderer/core/layout/layout_theme_mobile.h"
+
+namespace blink {
+
+class LayoutThemeTouchless final : public LayoutThemeMobile {
+ public:
+  static scoped_refptr<LayoutTheme> Create();
+  bool DelegatesMenuListRendering() const override { return true; }
+
+  bool IsFocusRingOutset() const override;
+
+ private:
+  ~LayoutThemeTouchless() override;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_THEME_TOUCHLESS_H_
diff --git a/third_party/blink/renderer/core/layout/scroll_anchor.cc b/third_party/blink/renderer/core/layout/scroll_anchor.cc
index 33870d9..caac1b7 100644
--- a/third_party/blink/renderer/core/layout/scroll_anchor.cc
+++ b/third_party/blink/renderer/core/layout/scroll_anchor.cc
@@ -97,7 +97,10 @@
       local_bounds.ShiftMaxYEdgeTo(max_y);
     }
   } else if (layout_object->IsText()) {
-    local_bounds.Unite(ToLayoutText(layout_object)->LinesBoundingBox());
+    LayoutRect bounds = ToLayoutText(layout_object)->PhysicalLinesBoundingBox();
+    if (UNLIKELY(layout_object->HasFlippedBlocksWritingMode()))
+      layout_object->ContainingBlock()->FlipForWritingMode(bounds);
+    local_bounds.Unite(bounds);
   } else {
     // Only LayoutBox and LayoutText are supported.
     NOTREACHED();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
index 4e0ca133..12d93b3 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
@@ -129,7 +129,7 @@
   return bounding_box;
 }
 
-LayoutRect LayoutSVGInlineText::LinesBoundingBox() const {
+LayoutRect LayoutSVGInlineText::PhysicalLinesBoundingBox() const {
   return EnclosingLayoutRect(FloatLinesBoundingBox());
 }
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h
index 8b1aeac..97e76f5 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h
@@ -75,7 +75,7 @@
       const InlineBox*,
       int caret_offset,
       LayoutUnit* extra_width_to_end_of_line = nullptr) const override;
-  LayoutRect LinesBoundingBox() const override;
+  LayoutRect PhysicalLinesBoundingBox() const override;
   InlineTextBox* CreateTextBox(int start, uint16_t length) override;
 
   LayoutRect VisualRectInDocument(VisualRectFlags) const final;
diff --git a/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc b/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
index fcf0d3b..48e64ea 100644
--- a/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
+++ b/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
@@ -30,12 +30,8 @@
       const LayoutBoxModelObject& ancestor,
       const LayoutRect& expected_visual_rect_in_ancestor) {
     LayoutRect rect = object.LocalVisualRect();
-    if (object.IsBox())
-      ToLayoutBox(object).FlipForWritingMode(rect);
-
     if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
       EXPECT_EQ(&ancestor, &object.ContainerForPaintInvalidation());
-
     CheckVisualRect(object, ancestor, rect, expected_visual_rect_in_ancestor);
   }
 
@@ -123,6 +119,45 @@
 
   LayoutRect original_rect(0, 60, 20, 80);
   LayoutRect rect = original_rect;
+  // For a LayoutText, the "local coordinate space" is actually the contents
+  // coordinate space of the containing block, so the following mappings are
+  // only affected by the geometry of the container, not related to where the
+  // text is laid out.
+  EXPECT_TRUE(text->MapToVisualRectInAncestorSpace(container, rect));
+  rect.Move(-container->ScrolledContentOffset());
+  EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
+
+  rect = original_rect;
+  EXPECT_TRUE(text->MapToVisualRectInAncestorSpace(&GetLayoutView(), rect));
+  EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40));
+
+  rect = LayoutRect(0, 60, 80, 0);
+  EXPECT_TRUE(
+      text->MapToVisualRectInAncestorSpace(container, rect, kEdgeInclusive));
+  rect.Move(-container->ScrolledContentOffset());
+  EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
+}
+
+TEST_P(VisualRectMappingTest, LayoutTextContainerFlippedWritingMode) {
+  SetBodyInnerHTML(R"HTML(
+    <style>body { margin: 0; }</style>
+    <div id='container' style='vertical-align: bottom; overflow: scroll;
+        width: 50px; height: 50px; writing-mode: vertical-rl'>
+      <span><img style='width: 20px; height: 100px'></span>
+      <span id='text'>text text text text text text text</span>
+    </div>
+  )HTML");
+
+  auto* container = To<LayoutBlock>(GetLayoutObjectByElementId("container"));
+  auto* text = GetLayoutObjectByElementId("text")->SlowFirstChild();
+
+  container->SetScrollTop(LayoutUnit(50));
+  UpdateAllLifecyclePhasesForTest();
+
+  // All results are the same as VisualRectMappingTest.LayoutText because all
+  // rects are in physical coordinates of the container's contents space.
+  LayoutRect original_rect(0, 60, 20, 80);
+  LayoutRect rect = original_rect;
   EXPECT_TRUE(text->MapToVisualRectInAncestorSpace(container, rect));
   rect.Move(-container->ScrolledContentOffset());
   EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
@@ -174,6 +209,45 @@
   EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
 }
 
+TEST_P(VisualRectMappingTest, LayoutInlineContainerFlippedWritingMode) {
+  GetDocument().SetBaseURLOverride(KURL("http://test.com"));
+  SetBodyInnerHTML(R"HTML(
+    <style>body { margin: 0; }</style>
+    <div id='container' style='overflow: scroll; width: 50px; height: 50px;
+        writing-mode: vertical-rl'>
+      <span><img style='width: 20px; height: 100px'></span>
+      <span id='leaf'></span>
+    </div>
+  )HTML");
+
+  auto* container = To<LayoutBlock>(GetLayoutObjectByElementId("container"));
+  LayoutObject* leaf = container->LastChild();
+
+  container->SetScrollTop(LayoutUnit(50));
+  UpdateAllLifecyclePhasesForTest();
+
+  // All results are the same as VisualRectMappingTest.LayoutInline because all
+  // rects are in physical coordinates.
+  LayoutRect original_rect(0, 60, 20, 80);
+  LayoutRect rect = original_rect;
+  EXPECT_TRUE(leaf->MapToVisualRectInAncestorSpace(container, rect));
+  rect.Move(-container->ScrolledContentOffset());
+  EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
+
+  rect = original_rect;
+  EXPECT_TRUE(leaf->MapToVisualRectInAncestorSpace(&GetLayoutView(), rect));
+  EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40));
+
+  // The span is empty.
+  CheckPaintInvalidationVisualRect(*leaf, GetLayoutView(), LayoutRect());
+
+  rect = LayoutRect(0, 60, 80, 0);
+  EXPECT_TRUE(
+      leaf->MapToVisualRectInAncestorSpace(container, rect, kEdgeInclusive));
+  rect.Move(-container->ScrolledContentOffset());
+  EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
+}
+
 TEST_P(VisualRectMappingTest, LayoutView) {
   GetDocument().SetBaseURLOverride(KURL("http://test.com"));
   SetBodyInnerHTML(R"HTML(
@@ -296,19 +370,11 @@
 
   auto* target = To<LayoutBlock>(GetLayoutObjectByElementId("target"));
   LayoutRect local_visual_rect = target->LocalVisualRect();
-  // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the
-  // origin)
   // 140 = width(100) + box_shadow_offset_x(40)
   // 70 = height(50) + box_shadow_offset_y(20)
-  EXPECT_EQ(LayoutRect(-40, 0, 140, 70), local_visual_rect);
+  EXPECT_EQ(LayoutRect(0, 0, 140, 70), local_visual_rect);
 
   LayoutRect rect = local_visual_rect;
-  // TODO(wkorman): The calls to flipForWritingMode() here and in other test
-  // cases below are necessary because mapToVisualRectInAncestorSpace()
-  // currently expects the input rect to be in "physical coordinates" (*not*
-  // "physical coordinates with flipped block-flow direction"), see
-  // LayoutBoxModelObject.h.
-  target->FlipForWritingMode(rect);
   EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(target, rect));
   // This rect is in physical coordinates of target.
   EXPECT_EQ(LayoutRect(0, 0, 140, 70), rect);
@@ -329,21 +395,17 @@
 
   auto* target = To<LayoutBlock>(GetLayoutObjectByElementId("target"));
   LayoutRect target_local_visual_rect = target->LocalVisualRect();
-  // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the
-  // origin)
   // 140 = width(100) + box_shadow_offset_x(40)
   // 110 = height(90) + box_shadow_offset_y(20)
-  EXPECT_EQ(LayoutRect(-40, 0, 140, 110), target_local_visual_rect);
+  EXPECT_EQ(LayoutRect(0, 0, 140, 110), target_local_visual_rect);
 
   LayoutRect rect = target_local_visual_rect;
-  target->FlipForWritingMode(rect);
   EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(target, rect));
   // This rect is in physical coordinates of target.
   EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
 
   auto* container = To<LayoutBlock>(GetLayoutObjectByElementId("container"));
   rect = target_local_visual_rect;
-  target->FlipForWritingMode(rect);
   EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(container, rect));
   // 100 is the physical x location of target in container.
   EXPECT_EQ(LayoutRect(100, 0, 140, 110), rect);
@@ -354,11 +416,9 @@
   LayoutRect container_local_visual_rect = container->LocalVisualRect();
   EXPECT_EQ(LayoutRect(0, 0, 200, 100), container_local_visual_rect);
   rect = container_local_visual_rect;
-  container->FlipForWritingMode(rect);
   EXPECT_TRUE(container->MapToVisualRectInAncestorSpace(container, rect));
   EXPECT_EQ(LayoutRect(0, 0, 200, 100), rect);
   rect = container_local_visual_rect;
-  container->FlipForWritingMode(rect);
   EXPECT_TRUE(
       container->MapToVisualRectInAncestorSpace(&GetLayoutView(), rect));
   EXPECT_EQ(LayoutRect(222, 111, 200, 100), rect);
@@ -445,20 +505,16 @@
 
   auto* target = To<LayoutBlock>(GetLayoutObjectByElementId("target"));
   LayoutRect target_local_visual_rect = target->LocalVisualRect();
-  // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the
-  // origin)
   // 140 = width(100) + box_shadow_offset_x(40)
   // 110 = height(90) + box_shadow_offset_y(20)
-  EXPECT_EQ(LayoutRect(-40, 0, 140, 110), target_local_visual_rect);
+  EXPECT_EQ(LayoutRect(0, 0, 140, 110), target_local_visual_rect);
 
   LayoutRect rect = target_local_visual_rect;
-  target->FlipForWritingMode(rect);
   EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(target, rect));
   // This rect is in physical coordinates of target.
   EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
 
   rect = target_local_visual_rect;
-  target->FlipForWritingMode(rect);
   EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(container, rect));
   rect.Move(-container->ScrolledContentOffset());
   // -2 = target_physical_x(100) + container_border_left(40) - scroll_left(142)
@@ -486,7 +542,6 @@
   EXPECT_EQ(LayoutRect(0, 0, 110, 120), container_local_visual_rect);
 
   rect = container_local_visual_rect;
-  container->FlipForWritingMode(rect);
   EXPECT_TRUE(container->MapToVisualRectInAncestorSpace(container, rect));
   EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect);
 
@@ -554,20 +609,16 @@
 
   auto* target = To<LayoutBlock>(GetLayoutObjectByElementId("target"));
   LayoutRect target_local_visual_rect = target->LocalVisualRect();
-  // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the
-  // origin)
   // 140 = width(100) + box_shadow_offset_x(40)
   // 110 = height(90) + box_shadow_offset_y(20)
-  EXPECT_EQ(LayoutRect(-40, 0, 140, 110), target_local_visual_rect);
+  EXPECT_EQ(LayoutRect(0, 0, 140, 110), target_local_visual_rect);
 
   LayoutRect rect = target_local_visual_rect;
-  target->FlipForWritingMode(rect);
   EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(target, rect));
   // This rect is in physical coordinates of target.
   EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
 
   rect = target_local_visual_rect;
-  target->FlipForWritingMode(rect);
   // 58 = target_physical_x(100) + container_border_left(40) - scroll_left(58)
   CheckVisualRect(*target, *container, rect, LayoutRect(-10, 10, 140, 110));
   EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(container, rect));
@@ -769,6 +820,159 @@
   }
 }
 
+TEST_P(VisualRectMappingTest, FloatUnderInlineVerticalRL) {
+  SetBodyInnerHTML(R"HTML(
+    <div style='position: absolute; writing-mode: vertical-rl;
+                top: 55px; left: 66px; width: 600px; height: 400px'>
+      <span id='span' style='position: relative; top: 100px; left: -200px'>
+        <div id='target' style='float: left; width: 33px; height: 44px'>
+        </div>
+      </span>
+    </div>
+  )HTML");
+
+  auto* span = ToLayoutBoxModelObject(GetLayoutObjectByElementId("span"));
+  auto* target = ToLayoutBox(GetLayoutObjectByElementId("target"));
+
+  auto target_visual_rect = target->LocalVisualRect();
+  EXPECT_EQ(LayoutRect(0, 0, 33, 44), target_visual_rect);
+
+  auto rect = target_visual_rect;
+  EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(&GetLayoutView(), rect));
+  if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+    // LayoutNG inline-level floats are children of their inline-level
+    // containers. As such they are positioned relative to their inline-level
+    // container, (and shifted by an additional 200,100 in this case).
+    EXPECT_EQ(LayoutRect(66 + 600 - 200 - 33, 55 + 100, 33, 44), rect);
+  } else {
+    EXPECT_EQ(LayoutRect(66 + 600 - 33, 55, 33, 44), rect);
+  }
+  EXPECT_EQ(EnclosingIntRect(rect), target->FirstFragment().VisualRect());
+
+  // An inline object's coordinate space is its containing block's coordinate
+  // space shifted by the inline's relative offset. |target|'s left is 100 from
+  // the right edge of the coordinate space whose width is 600.
+  rect = target_visual_rect;
+  if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+    CheckVisualRect(*target, *span, rect, LayoutRect(600 - 33, 0, 33, 44));
+  } else {
+    CheckVisualRect(*target, *span, rect,
+                    LayoutRect(600 + 200 - 33, -100, 33, 44));
+  }
+}
+
+TEST_P(VisualRectMappingTest, InlineBlock) {
+  SetBodyInnerHTML(R"HTML(
+    <div style="position: absolute; top: 55px; left: 66px">
+      <span id="span" style="position: relative; top: 100px; left: 200px">
+        <div id="target"
+             style="display: inline-block; width: 33px; height: 44px">
+        </div>
+      </span>
+    </div>
+  )HTML");
+
+  auto* span = ToLayoutBoxModelObject(GetLayoutObjectByElementId("span"));
+  auto* target = ToLayoutBox(GetLayoutObjectByElementId("target"));
+
+  auto target_visual_rect = target->LocalVisualRect();
+  EXPECT_EQ(LayoutRect(0, 0, 33, 44), target_visual_rect);
+
+  auto rect = target_visual_rect;
+  EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(&GetLayoutView(), rect));
+  EXPECT_EQ(LayoutRect(266, 155, 33, 44), rect);
+  EXPECT_EQ(EnclosingIntRect(rect), target->FirstFragment().VisualRect());
+
+  rect = target_visual_rect;
+  CheckVisualRect(*target, *span, rect, LayoutRect(0, 0, 33, 44));
+}
+
+TEST_P(VisualRectMappingTest, InlineBlockVerticalRL) {
+  SetBodyInnerHTML(R"HTML(
+    <div style='position: absolute; writing-mode: vertical-rl;
+                top: 55px; left: 66px; width: 600px; height: 400px'>
+      <span id="span" style="position: relative; top: 100px; left: -200px">
+        <div id="target"
+             style="display: inline-block; width: 33px; height: 44px">
+        </div>
+      </span>
+    </div>
+  )HTML");
+
+  auto* span = ToLayoutBoxModelObject(GetLayoutObjectByElementId("span"));
+  auto* target = ToLayoutBox(GetLayoutObjectByElementId("target"));
+
+  auto target_visual_rect = target->LocalVisualRect();
+  EXPECT_EQ(LayoutRect(0, 0, 33, 44), target_visual_rect);
+
+  auto rect = target_visual_rect;
+  EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(&GetLayoutView(), rect));
+  EXPECT_EQ(LayoutRect(66 + 600 - 200 - 33, 155, 33, 44), rect);
+  EXPECT_EQ(EnclosingIntRect(rect), target->FirstFragment().VisualRect());
+
+  // An inline object's coordinate space is its containing block's coordinate
+  // space shifted by the inline's relative offset. |target|'s left is -33 from
+  // the right edge of the coordinate space whose width is 600.
+  rect = target_visual_rect;
+  CheckVisualRect(*target, *span, rect, LayoutRect(600 - 33, 0, 33, 44));
+}
+
+TEST_P(VisualRectMappingTest, AbsoluteUnderRelativeInline) {
+  SetBodyInnerHTML(R"HTML(
+    <div style='position: absolute; top: 55px; left: 66px'>
+      <span id='span' style='position: relative; top: 100px; left: 200px'>
+        <div id='target' style='position: absolute; top: 50px; left: 100px;
+                                width: 33px; height: 44px'>
+        </div>
+      </span>
+    </div>
+  )HTML");
+
+  auto* span = ToLayoutBoxModelObject(GetLayoutObjectByElementId("span"));
+  auto* target = ToLayoutBox(GetLayoutObjectByElementId("target"));
+
+  auto target_visual_rect = target->LocalVisualRect();
+  EXPECT_EQ(LayoutRect(0, 0, 33, 44), target_visual_rect);
+
+  auto rect = target_visual_rect;
+  EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(&GetLayoutView(), rect));
+  EXPECT_EQ(LayoutRect(66 + 200 + 100, 55 + 100 + 50, 33, 44), rect);
+  EXPECT_EQ(EnclosingIntRect(rect), target->FirstFragment().VisualRect());
+
+  rect = target_visual_rect;
+  CheckVisualRect(*target, *span, rect, LayoutRect(100, 50, 33, 44));
+}
+
+TEST_P(VisualRectMappingTest, AbsoluteUnderRelativeInlineVerticalRL) {
+  SetBodyInnerHTML(R"HTML(
+    <div style='position: absolute; writing-mode: vertical-rl;
+                top: 55px; left: 66px; width: 600px; height: 400px'>
+      <span id='span' style='position: relative; top: 100px; left: -200px'>
+        <div id='target' style='position: absolute; top: 50px; left: 100px;
+                                width: 33px; height: 44px'>
+        </div>
+      </span>
+    </div>
+  )HTML");
+
+  auto* span = ToLayoutBoxModelObject(GetLayoutObjectByElementId("span"));
+  auto* target = ToLayoutBox(GetLayoutObjectByElementId("target"));
+
+  auto target_visual_rect = target->LocalVisualRect();
+  EXPECT_EQ(LayoutRect(0, 0, 33, 44), target_visual_rect);
+
+  auto rect = target_visual_rect;
+  EXPECT_TRUE(target->MapToVisualRectInAncestorSpace(&GetLayoutView(), rect));
+  EXPECT_EQ(LayoutRect(66 + 600 - 200 + 100, 55 + 100 + 50, 33, 44), rect);
+  EXPECT_EQ(EnclosingIntRect(rect), target->FirstFragment().VisualRect());
+
+  // An inline object's coordinate space is its containing block's coordinate
+  // space shifted by the inline's relative offset. |target|'s left is 100 from
+  // the right edge of the coordinate space whose width is 600.
+  rect = target_visual_rect;
+  CheckVisualRect(*target, *span, rect, LayoutRect(600 + 100, 50, 33, 44));
+}
+
 TEST_P(VisualRectMappingTest, ShouldAccountForPreserve3d) {
   EnableCompositing();
   SetBodyInnerHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 5ba9b15..0785b45 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -402,15 +402,6 @@
   frame_->GetDocument()->CheckCompleted();
 }
 
-bool FrameLoader::AllAncestorsAreComplete() const {
-  for (Frame* ancestor = frame_; ancestor;
-       ancestor = ancestor->Tree().Parent()) {
-    if (ancestor->IsLoading())
-      return false;
-  }
-  return true;
-}
-
 void FrameLoader::DidFinishNavigation() {
   // We should have either finished the provisional or committed navigation if
   // this is called. Only delcare the whole frame finished if neither is in
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h
index 7b5c50c..ec012d0d 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.h
+++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -191,8 +191,6 @@
 
   FrameLoaderStateMachine* StateMachine() const { return &state_machine_; }
 
-  bool AllAncestorsAreComplete() const;  // including this
-
   bool ShouldClose(bool is_reload = false);
   void DispatchUnloadEvent();
 
diff --git a/third_party/blink/renderer/core/loader/text_track_loader.cc b/third_party/blink/renderer/core/loader/text_track_loader.cc
index 4998ea7..32f6cd9 100644
--- a/third_party/blink/renderer/core/loader/text_track_loader.cc
+++ b/third_party/blink/renderer/core/loader/text_track_loader.cc
@@ -29,6 +29,7 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
 #include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
@@ -76,7 +77,7 @@
     return;
 
   if (!cue_parser_)
-    cue_parser_ = VTTParser::Create(this, GetDocument());
+    cue_parser_ = MakeGarbageCollected<VTTParser>(this, GetDocument());
 
   cue_parser_->ParseBytes(data, length);
 }
diff --git a/third_party/blink/renderer/core/loader/text_track_loader.h b/third_party/blink/renderer/core/loader/text_track_loader.h
index b3dac32..2dd125d3 100644
--- a/third_party/blink/renderer/core/loader/text_track_loader.h
+++ b/third_party/blink/renderer/core/loader/text_track_loader.h
@@ -46,15 +46,10 @@
 
 class TextTrackLoader final : public GarbageCollectedFinalized<TextTrackLoader>,
                               public RawResourceClient,
-                              private VTTParserClient {
+                              public VTTParserClient {
   USING_GARBAGE_COLLECTED_MIXIN(TextTrackLoader);
 
  public:
-  static TextTrackLoader* Create(TextTrackLoaderClient& client,
-                                 Document& document) {
-    return MakeGarbageCollected<TextTrackLoader>(client, document);
-  }
-
   TextTrackLoader(TextTrackLoaderClient&, Document&);
   ~TextTrackLoader() override;
 
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index 15d0f1b9..3fc3034 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -495,7 +495,6 @@
     return;
   DCHECK_NE(state, PageLifecycleState::kUnknown);
 
-  if (RuntimeEnabledFeatures::PageLifecycleEnabled()) {
     if (state == PageLifecycleState::kFrozen) {
       for (Frame* frame = main_frame_.Get(); frame;
            frame = frame->Tree().TraverseNext()) {
@@ -512,7 +511,6 @@
         frame->DidResume();
       }
     }
-  }
   page_lifecycle_state_ = state;
 }
 
diff --git a/third_party/blink/renderer/core/paint/css_mask_painter.cc b/third_party/blink/renderer/core/paint/css_mask_painter.cc
index 5f092f0d..2473ec6 100644
--- a/third_party/blink/renderer/core/paint/css_mask_painter.cc
+++ b/third_party/blink/renderer/core/paint/css_mask_painter.cc
@@ -47,9 +47,7 @@
     // there could be one box in multiple fragments or multiple boxes.
     // Either way here we are only interested in the bounding box of them.
     DCHECK(object.IsLayoutInline());
-    maximum_mask_region = ToLayoutInline(object).LinesBoundingBox();
-    if (object.HasFlippedBlocksWritingMode())
-      object.ContainingBlock()->FlipForWritingMode(maximum_mask_region);
+    maximum_mask_region = ToLayoutInline(object).PhysicalLinesBoundingBox();
   }
   if (style.HasMaskBoxImageOutsets())
     maximum_mask_region.Expand(style.MaskBoxImageOutsets());
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
index 0b28009f..7a26120 100644
--- a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
@@ -123,6 +123,13 @@
     OnLargestImagePaintDetected(largest_image_record);
     frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming();
   }
+  if (largest_image_paint_) {
+    frame_view_->GetPaintTimingDetector().NotifyLargestImage(
+        largest_image_paint_->paint_time, largest_image_paint_->first_size);
+  } else {
+    frame_view_->GetPaintTimingDetector().NotifyLargestImage(base::TimeTicks(),
+                                                             0);
+  }
   // TODO(crbug/949974): when the largest image is still loading, we should
   // update the result as the current time.
 }
@@ -172,6 +179,7 @@
   if (notify_swap_time_override_for_testing_) {
     // Run is not to run the |callback|, but to queue it.
     notify_swap_time_override_for_testing_.Run(std::move(callback));
+    num_pending_swap_callbacks_++;
     return;
   }
   // ReportSwapTime on layerTreeView will queue a swap-promise, the callback is
@@ -179,7 +187,9 @@
   LocalFrame& frame = frame_view_->GetFrame();
   if (!frame.GetPage())
     return;
+
   frame.GetPage()->GetChromeClient().NotifySwapTime(frame, std::move(callback));
+  num_pending_swap_callbacks_++;
 }
 
 void ImagePaintTimingDetector::ReportSwapTime(
@@ -191,6 +201,8 @@
   records_manager_.AssignPaintTimeToRegisteredQueuedNodes(
       timestamp, last_queued_frame_index);
   UpdateCandidate();
+  num_pending_swap_callbacks_--;
+  DCHECK_GE(num_pending_swap_callbacks_, 0);
 }
 
 void ImageRecordsManager::AssignPaintTimeToRegisteredQueuedNodes(
@@ -450,6 +462,10 @@
   is_recording_ = false;
 }
 
+bool ImagePaintTimingDetector::FinishedReportingImages() const {
+  return !is_recording_ && num_pending_swap_callbacks_ == 0;
+}
+
 ImageRecord* ImageRecordsManager::FindLargestPaintCandidate() {
   DCHECK_EQ(visible_node_map_.size() + visible_background_image_map_.size(),
             size_ordered_set_.size());
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector.h b/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
index 9678bfb..c740ebf 100644
--- a/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
+++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
@@ -176,13 +176,6 @@
   void OnPaintFinished();
   void NotifyNodeRemoved(DOMNodeId);
   void NotifyBackgroundImageRemoved(DOMNodeId, const ImageResourceContent*);
-  base::TimeTicks LargestImagePaint() const {
-    return !largest_image_paint_ ? base::TimeTicks()
-                                 : largest_image_paint_->paint_time;
-  }
-  uint64_t LargestImagePaintSize() const {
-    return !largest_image_paint_ ? 0 : largest_image_paint_->first_size;
-  }
   // After the method being called, the detector stops to record new entries and
   // node removal. But it still observe the loading status. In other words, if
   // an image is recorded before stopping recording, and finish loading after
@@ -190,6 +183,7 @@
   // finished.
   void StopRecordEntries();
   bool IsRecording() const { return is_recording_; }
+  bool FinishedReportingImages() const;
   void Trace(blink::Visitor*);
 
  private:
@@ -223,6 +217,10 @@
   // no effect on recording the loading status.
   bool is_recording_ = true;
 
+  // Used to determine how many swap callbacks are pending. In combination with
+  // |is_recording|, helps determine whether this detector can be destroyed.
+  int num_pending_swap_callbacks_ = 0;
+
   bool need_update_timing_at_frame_end_ = false;
 
   ImageRecord* largest_image_paint_ = nullptr;
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
index 5a13c44..329ab2e 100644
--- a/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
+++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
@@ -67,57 +67,60 @@
 
   void ReplaceCallBackQueue(PaintTimingDetector& detector) {
     detector.GetImagePaintTimingDetector()
-        .notify_swap_time_override_for_testing_ =
+        ->notify_swap_time_override_for_testing_ =
         base::BindRepeating(&ImagePaintTimingDetectorTest::FakeNotifySwapTime,
                             base::Unretained(this));
   }
   ImageRecord* FindLargestPaintCandidate() {
     return GetPaintTimingDetector()
         .GetImagePaintTimingDetector()
-        .records_manager_.FindLargestPaintCandidate();
+        ->records_manager_.FindLargestPaintCandidate();
   }
 
   ImageRecord* FindChildFrameLargestPaintCandidate() {
     return GetChildFrameView()
         .GetPaintTimingDetector()
         .GetImagePaintTimingDetector()
-        .records_manager_.FindLargestPaintCandidate();
+        ->records_manager_.FindLargestPaintCandidate();
   }
 
   size_t CountVisibleImageRecords() {
+    if (!GetPaintTimingDetector().GetImagePaintTimingDetector())
+      return 0;
+
     return GetPaintTimingDetector()
         .GetImagePaintTimingDetector()
-        .records_manager_.visible_node_map_.size();
+        ->records_manager_.visible_node_map_.size();
   }
 
   size_t CountVisibleBackgroundImageRecords() {
     return GetPaintTimingDetector()
         .GetImagePaintTimingDetector()
-        .records_manager_.visible_background_image_map_.size();
+        ->records_manager_.visible_background_image_map_.size();
   }
 
   size_t CountChildFrameRecords() {
     return GetChildPaintTimingDetector()
         .GetImagePaintTimingDetector()
-        .records_manager_.visible_node_map_.size();
+        ->records_manager_.visible_node_map_.size();
   }
 
   size_t CountRankingSetRecords() {
     return GetPaintTimingDetector()
         .GetImagePaintTimingDetector()
-        .records_manager_.size_ordered_set_.size();
+        ->records_manager_.size_ordered_set_.size();
   }
 
   void UpdateCandidate() {
     return GetPaintTimingDetector()
         .GetImagePaintTimingDetector()
-        .UpdateCandidate();
+        ->UpdateCandidate();
   }
 
   TimeTicks LargestPaintStoredResult() {
     ImageRecord* record = GetPaintTimingDetector()
                               .GetImagePaintTimingDetector()
-                              .largest_image_paint_;
+                              ->largest_image_paint_;
     return !record ? base::TimeTicks() : record->paint_time;
   }
 
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index a344d6c3..c7008b0 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -664,25 +664,19 @@
              : layout_object.PartialInvalidationVisualRect();
 }
 
-bool NGPaintFragment::FlippedLocalVisualRectFor(
-    const LayoutObject* layout_object,
-    LayoutRect* visual_rect) {
-  auto fragments = InlineFragmentsFor(layout_object);
+base::Optional<LayoutRect> NGPaintFragment::LocalVisualRectFor(
+    const LayoutObject& layout_object) {
+  auto fragments = InlineFragmentsFor(&layout_object);
   if (!fragments.IsInLayoutNGInlineFormattingContext())
-    return false;
+    return base::nullopt;
 
+  LayoutRect visual_rect;
   for (NGPaintFragment* fragment : fragments) {
     PhysicalRect child_visual_rect = fragment->SelfInkOverflow();
     child_visual_rect.offset += fragment->InlineOffsetToContainerBox();
-    visual_rect->Unite(child_visual_rect.ToLayoutRect());
+    visual_rect.Unite(child_visual_rect.ToLayoutRect());
   }
-  if (!layout_object->HasFlippedBlocksWritingMode())
-    return true;
-
-  NGPaintFragment* container = GetForInlineContainer(layout_object);
-  DCHECK(container);
-  ToLayoutBox(container->GetLayoutObject())->FlipForWritingMode(*visual_rect);
-  return true;
+  return visual_rect;
 }
 
 void NGPaintFragment::AddSelfOutlineRect(Vector<LayoutRect>* outline_rects,
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
index 84ce7595..65aa96b 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -284,13 +284,9 @@
   // Mark the line box that contains this fragment dirty.
   void MarkContainingLineBoxDirty();
 
-  // Computes LocalVisualRect for an inline LayoutObject in the
-  // LayoutObject::LocalVisualRect semantics; i.e., physical coordinates with
-  // flipped block-flow direction. See layout/README.md for the coordinate
-  // spaces.
-  // Returns false if the LayoutObject is not in LayoutNG inline formatting
-  // context.
-  static bool FlippedLocalVisualRectFor(const LayoutObject*, LayoutRect*);
+  // Computes LocalVisualRect for an inline LayoutObject. Returns nullopt if the
+  // LayoutObject is not in LayoutNG inline formatting context.
+  static base::Optional<LayoutRect> LocalVisualRectFor(const LayoutObject&);
 
  private:
   static scoped_refptr<NGPaintFragment> CreateOrReuse(
diff --git a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
index d8b78e7b..81cbf42d 100644
--- a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
+++ b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
@@ -305,7 +305,7 @@
 #endif
   if (context_.NeedsVisualRectUpdate(object_)) {
     new_selection_rect = context_.MapLocalRectToVisualRect(
-        object_, object_.LocalSelectionRect());
+        object_, object_.LocalSelectionVisualRect());
   } else {
     new_selection_rect = old_selection_rect;
   }
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.cc b/third_party/blink/renderer/core/paint/paint_invalidator.cc
index 63239402..8b798e3 100644
--- a/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -80,25 +80,13 @@
          // objects, for carets, selections, etc.
          object.IsBoxModelObject() || object.IsText());
 
-  // The flip below is required because local visual rects are currently in
-  // "physical coordinates with flipped block-flow direction" (see
-  // LayoutBoxModelObject.h) but we need them to be in physical coordinates.
-  auto rect = local_rect;
-  if (object.IsBox()) {
-    ToLayoutBox(object).FlipForWritingMode(rect);
-  } else {
-    // Also convert the rect for non-boxes into physical coordinates before
-    // applying paint offset.
-    // TODO(wangxianzhu): Avoid ContainingBlock().
-    object.ContainingBlock()->FlipForWritingMode(rect);
-  }
-
   // Unite visual rect with clip path bounding rect.
   // It is because the clip path display items are owned by the layout object
   // who has the clip path, and uses its visual rect as bounding rect too.
   // Usually it is done at layout object level and included as a part of
   // local visual overflow, but clip-path can be a reference to SVG, and we
   // have to wait until pre-paint to ensure clean layout.
+  auto rect = local_rect;
   if (base::Optional<FloatRect> clip_path_bounding_box =
           ClipPathClipper::LocalClipPathBoundingBox(object))
     rect.Unite(LayoutRect(EnclosingIntRect(*clip_path_bounding_box)));
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index b2d47e5d..70bedf0 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -866,7 +866,7 @@
   } else if (GetLayoutObject().IsInline() &&
              GetLayoutObject().IsLayoutInline()) {
     LayoutInline& inline_flow = ToLayoutInline(GetLayoutObject());
-    IntRect line_box = EnclosingIntRect(inline_flow.LinesBoundingBox());
+    IntRect line_box = EnclosingIntRect(inline_flow.PhysicalLinesBoundingBox());
     size_ = LayoutSize(line_box.Size());
   } else if (LayoutBox* box = GetLayoutBox()) {
     size_ = box->Size();
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index 366ad30..c60cb58 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -2030,8 +2030,7 @@
     const PaintLayer& ancestor_layer) {
   TransformState transform_state(TransformState::kApplyTransformDirection,
                                  FloatPoint(local_rect.Location()));
-  box.MapLocalToAncestor(&ancestor_layer.GetLayoutObject(), transform_state,
-                         kApplyContainerFlip);
+  box.MapLocalToAncestor(&ancestor_layer.GetLayoutObject(), transform_state, 0);
   transform_state.Flatten();
   return LayoutRect(LayoutPoint(transform_state.LastPlanarPoint()),
                     local_rect.Size());
@@ -2080,7 +2079,6 @@
     // instead of falling back to the bounds of the enclosing block.
     if (!object.IsSVG()) {
       local_bounds = object.LocalVisualRect();
-      local_space_object->FlipForWritingMode(local_bounds);
     } else {
       local_bounds = LayoutRect(SVGLayoutSupport::LocalVisualRect(object));
     }
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
index 20b1d48..28f2482 100644
--- a/third_party/blink/renderer/core/paint/paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -55,8 +55,16 @@
           MakeGarbageCollected<ImagePaintTimingDetector>(frame_view)) {}
 
 void PaintTimingDetector::NotifyPaintFinished() {
-  text_paint_timing_detector_->OnPaintFinished();
-  image_paint_timing_detector_->OnPaintFinished();
+  if (text_paint_timing_detector_) {
+    text_paint_timing_detector_->OnPaintFinished();
+    if (text_paint_timing_detector_->FinishedReportingText())
+      text_paint_timing_detector_ = nullptr;
+  }
+  if (image_paint_timing_detector_) {
+    image_paint_timing_detector_->OnPaintFinished();
+    if (image_paint_timing_detector_->FinishedReportingImages())
+      image_paint_timing_detector_ = nullptr;
+  }
 }
 
 // static
@@ -72,17 +80,17 @@
   LayoutObject* object = node->GetLayoutObject();
   if (!object)
     return;
-  if (!IsBackgroundImageContentful(*object, *image))
-    return;
   LocalFrameView* frame_view = object->GetFrameView();
   if (!frame_view)
     return;
-  if (!cached_image)
+  PaintTimingDetector& detector = frame_view->GetPaintTimingDetector();
+  if (!detector.GetImagePaintTimingDetector())
+    return;
+  if (!IsBackgroundImageContentful(*object, *image))
     return;
   if (!object->HasNonZeroEffectiveOpacity())
     return;
-  PaintTimingDetector& detector = frame_view->GetPaintTimingDetector();
-  detector.GetImagePaintTimingDetector().RecordBackgroundImage(
+  detector.GetImagePaintTimingDetector()->RecordBackgroundImage(
       *object, image->Size(), cached_image, current_paint_chunk_properties);
 }
 
@@ -100,8 +108,10 @@
   if (!object.HasNonZeroEffectiveOpacity())
     return;
   PaintTimingDetector& detector = frame_view->GetPaintTimingDetector();
-  detector.GetImagePaintTimingDetector().RecordImage(
-      object, intrinsic_size, cached_image, current_paint_chunk_properties);
+  if (detector.GetImagePaintTimingDetector()) {
+    detector.GetImagePaintTimingDetector()->RecordImage(
+        object, intrinsic_size, cached_image, current_paint_chunk_properties);
+  }
 }
 
 // static
@@ -114,16 +124,21 @@
   if (!object.HasNonZeroEffectiveOpacity())
     return;
   PaintTimingDetector& detector = frame_view->GetPaintTimingDetector();
-  detector.GetTextPaintTimingDetector().RecordText(
-      object, current_paint_chunk_properties);
+  if (detector.GetTextPaintTimingDetector()) {
+    detector.GetTextPaintTimingDetector()->RecordText(
+        object, current_paint_chunk_properties);
+  }
 }
 
 void PaintTimingDetector::NotifyNodeRemoved(const LayoutObject& object) {
   DOMNodeId node_id = DOMNodeIds::ExistingIdForNode(object.GetNode());
   if (node_id == kInvalidDOMNodeId)
     return;
-  text_paint_timing_detector_->NotifyNodeRemoved(node_id);
-  image_paint_timing_detector_->NotifyNodeRemoved(node_id);
+
+  if (text_paint_timing_detector_)
+    text_paint_timing_detector_->NotifyNodeRemoved(node_id);
+  if (image_paint_timing_detector_)
+    image_paint_timing_detector_->NotifyNodeRemoved(node_id);
 }
 
 void PaintTimingDetector::NotifyBackgroundImageRemoved(
@@ -132,8 +147,10 @@
   DOMNodeId node_id = DOMNodeIds::ExistingIdForNode(object.GetNode());
   if (node_id == kInvalidDOMNodeId)
     return;
-  image_paint_timing_detector_->NotifyBackgroundImageRemoved(node_id,
-                                                             cached_image);
+  if (image_paint_timing_detector_) {
+    image_paint_timing_detector_->NotifyBackgroundImageRemoved(node_id,
+                                                               cached_image);
+  }
 }
 
 void PaintTimingDetector::NotifyInputEvent(WebInputEvent::Type type) {
@@ -142,20 +159,38 @@
       WebInputEvent::IsPinchGestureEventType(type)) {
     return;
   }
-  text_paint_timing_detector_->StopRecordEntries();
-  image_paint_timing_detector_->StopRecordEntries();
+  if (text_paint_timing_detector_)
+    text_paint_timing_detector_->StopRecordEntries();
+  if (image_paint_timing_detector_)
+    image_paint_timing_detector_->StopRecordEntries();
 }
 
 void PaintTimingDetector::NotifyScroll(ScrollType scroll_type) {
   if (scroll_type != kUserScroll && scroll_type != kCompositorScroll)
     return;
-  text_paint_timing_detector_->StopRecordEntries();
-  image_paint_timing_detector_->StopRecordEntries();
+  if (text_paint_timing_detector_)
+    text_paint_timing_detector_->StopRecordEntries();
+  if (image_paint_timing_detector_)
+    image_paint_timing_detector_->StopRecordEntries();
 }
 
 bool PaintTimingDetector::NeedToNotifyInputOrScroll() {
-  return text_paint_timing_detector_->IsRecording() ||
-         image_paint_timing_detector_->IsRecording();
+  return (text_paint_timing_detector_ &&
+          text_paint_timing_detector_->IsRecording()) ||
+         (image_paint_timing_detector_ &&
+          image_paint_timing_detector_->IsRecording());
+}
+
+void PaintTimingDetector::NotifyLargestImage(base::TimeTicks image_paint_time,
+                                             uint64_t image_paint_size) {
+  largest_image_paint_time_ = image_paint_time;
+  largest_image_paint_size_ = image_paint_size;
+}
+
+void PaintTimingDetector::NotifyLargestText(base::TimeTicks text_paint_time,
+                                            uint64_t text_paint_size) {
+  largest_text_paint_time_ = text_paint_time;
+  largest_text_paint_size_ = text_paint_size;
 }
 
 void PaintTimingDetector::DidChangePerformanceTiming() {
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.h b/third_party/blink/renderer/core/paint/paint_timing_detector.h
index 69a976c..2ad32710 100644
--- a/third_party/blink/renderer/core/paint/paint_timing_detector.h
+++ b/third_party/blink/renderer/core/paint/paint_timing_detector.h
@@ -51,6 +51,8 @@
   void NotifyInputEvent(WebInputEvent::Type);
   bool NeedToNotifyInputOrScroll();
   void NotifyScroll(ScrollType);
+  void NotifyLargestImage(base::TimeTicks, uint64_t size);
+  void NotifyLargestText(base::TimeTicks, uint64_t size);
   void DidChangePerformanceTiming();
 
   // |visual_rect| should be an object's bounding rect in the space of
@@ -58,18 +60,35 @@
   uint64_t CalculateVisualSize(const IntRect& visual_rect,
                                const PropertyTreeState&) const;
 
-  TextPaintTimingDetector& GetTextPaintTimingDetector() {
-    return *text_paint_timing_detector_;
+  TextPaintTimingDetector* GetTextPaintTimingDetector() {
+    return text_paint_timing_detector_;
   }
-  ImagePaintTimingDetector& GetImagePaintTimingDetector() {
-    return *image_paint_timing_detector_;
+  ImagePaintTimingDetector* GetImagePaintTimingDetector() {
+    return image_paint_timing_detector_;
   }
+  base::TimeTicks LargestImagePaint() const {
+    return largest_image_paint_time_;
+  }
+  uint64_t LargestImagePaintSize() const { return largest_image_paint_size_; }
+  base::TimeTicks LargestTextPaint() const { return largest_text_paint_time_; }
+  uint64_t LargestTextPaintSize() const { return largest_text_paint_size_; }
   void Trace(Visitor* visitor);
 
  private:
   Member<LocalFrameView> frame_view_;
+  // This member lives until the end of the paint phase after the largest text
+  // paint is found.
   Member<TextPaintTimingDetector> text_paint_timing_detector_;
+  // This member lives until the end of the paint phase after the largest image
+  // paint is found.
   Member<ImagePaintTimingDetector> image_paint_timing_detector_;
+
+  // Largest image information.
+  base::TimeTicks largest_image_paint_time_;
+  uint64_t largest_image_paint_size_ = 0;
+  // Largest text information.
+  base::TimeTicks largest_text_paint_time_;
+  uint64_t largest_text_paint_size_ = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
index 05d5a84..2774dc6 100644
--- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
+++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -50,13 +50,15 @@
   if (needs_tree_builder_context_update)
     GeometryMapper::ClearCache();
 
-  auto property_changed = VisualViewportPaintPropertyTreeBuilder::Update(
-      root_frame_view.GetPage()->GetVisualViewport(),
-      *context_storage_.back().tree_builder_context);
+  if (root_frame_view.GetFrame().IsMainFrame()) {
+    auto property_changed = VisualViewportPaintPropertyTreeBuilder::Update(
+        root_frame_view.GetPage()->GetVisualViewport(),
+        *context_storage_.back().tree_builder_context);
 
-  if (property_changed >
-      PaintPropertyChangeType::kChangedOnlyCompositedValues) {
-    root_frame_view.SetPaintArtifactCompositorNeedsUpdate();
+    if (property_changed >
+        PaintPropertyChangeType::kChangedOnlyCompositedValues) {
+      root_frame_view.SetPaintArtifactCompositorNeedsUpdate();
+    }
   }
 
   Walk(root_frame_view);
@@ -250,7 +252,7 @@
     const PrePaintTreeWalkContext& context) {
   if ((RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() ||
        RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) &&
-      frame_view.GetFrame().IsLocalRoot() &&
+      frame_view.GetFrame().IsMainFrame() &&
       frame_view.GetPage()->GetVisualViewport().NeedsPaintPropertyUpdate())
     return true;
 
diff --git a/third_party/blink/renderer/core/paint/replaced_painter.cc b/third_party/blink/renderer/core/paint/replaced_painter.cc
index 685d126..41c7386e9 100644
--- a/third_party/blink/renderer/core/paint/replaced_painter.cc
+++ b/third_party/blink/renderer/core/paint/replaced_painter.cc
@@ -179,7 +179,8 @@
   if (draw_selection_tint && !DrawingRecorder::UseCachedDrawingIfPossible(
                                  local_paint_info.context, layout_replaced_,
                                  DisplayItem::kSelectionTint)) {
-    LayoutRect selection_painting_rect = layout_replaced_.LocalSelectionRect();
+    LayoutRect selection_painting_rect =
+        layout_replaced_.LocalSelectionVisualRect();
     selection_painting_rect.MoveBy(paint_offset);
     IntRect selection_painting_int_rect =
         PixelSnappedIntRect(selection_painting_rect);
@@ -213,9 +214,8 @@
       layout_replaced_.StyleRef().Visibility() != EVisibility::kVisible)
     return false;
 
-  LayoutRect local_rect(layout_replaced_.VisualOverflowRect());
-  local_rect.Unite(layout_replaced_.LocalSelectionRect());
-  layout_replaced_.FlipForWritingMode(local_rect);
+  LayoutRect local_rect(layout_replaced_.PhysicalVisualOverflowRect());
+  local_rect.Unite(layout_replaced_.LocalSelectionVisualRect());
   if (!paint_state.LocalRectIntersectsCullRect(local_rect))
     return false;
 
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
index 555003d..413147d 100644
--- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -86,6 +86,8 @@
     OnLargestTextDetected(*candidate);
     frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming();
   }
+  frame_view_->GetPaintTimingDetector().NotifyLargestText(
+      largest_text_paint_, largest_text_paint_size_);
 }
 
 void TextPaintTimingDetector::OnPaintFinished() {
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
index fa56650..6cd1b60 100644
--- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
+++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -118,10 +118,11 @@
   void OnPaintFinished();
   void NotifyNodeRemoved(DOMNodeId);
   TextRecord* FindLargestPaintCandidate();
-  base::TimeTicks LargestTextPaint() const { return largest_text_paint_; }
-  uint64_t LargestTextPaintSize() const { return largest_text_paint_size_; }
   void StopRecordEntries();
   bool IsRecording() const { return is_recording_; }
+  bool FinishedReportingText() const {
+    return !is_recording_ && !need_update_timing_at_frame_end_;
+  }
   void Trace(blink::Visitor*);
 
  private:
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
index e5a101d..04446ab 100644
--- a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
+++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
@@ -38,66 +38,70 @@
   LocalFrameView& GetChildFrameView() { return *ChildFrame().View(); }
 
   unsigned CountVisibleTexts() {
+    if (!GetPaintTimingDetector().GetTextPaintTimingDetector())
+      return 0u;
+
     return GetPaintTimingDetector()
                .GetTextPaintTimingDetector()
-               .records_manager_.visible_node_map_.size() -
+               ->records_manager_.visible_node_map_.size() -
            GetPaintTimingDetector()
                .GetTextPaintTimingDetector()
-               .records_manager_.detached_ids_.size();
+               ->records_manager_.detached_ids_.size();
   }
 
   unsigned CountRankingSetSize() {
     return GetPaintTimingDetector()
         .GetTextPaintTimingDetector()
-        .records_manager_.size_ordered_set_.size();
+        ->records_manager_.size_ordered_set_.size();
   }
 
   unsigned CountDetachedTexts() {
     return GetPaintTimingDetector()
         .GetTextPaintTimingDetector()
-        .records_manager_.detached_ids_.size();
+        ->records_manager_.detached_ids_.size();
   }
 
   void InvokeCallback() {
-    TextPaintTimingDetector& detector =
+    TextPaintTimingDetector* detector =
         GetPaintTimingDetector().GetTextPaintTimingDetector();
-    detector.ReportSwapTime(WebWidgetClient::SwapResult::kDidSwap,
-                            CurrentTimeTicks());
+    detector->ReportSwapTime(WebWidgetClient::SwapResult::kDidSwap,
+                             CurrentTimeTicks());
   }
 
   TimeTicks LargestPaintStoredResult() {
     return GetPaintTimingDetector()
         .GetTextPaintTimingDetector()
-        .largest_text_paint_;
+        ->largest_text_paint_;
   }
 
   // This only triggers ReportSwapTime in main frame.
   void UpdateAllLifecyclePhasesAndSimulateSwapTime() {
     UpdateAllLifecyclePhasesForTest();
-    TextPaintTimingDetector& detector =
+    TextPaintTimingDetector* detector =
         GetPaintTimingDetector().GetTextPaintTimingDetector();
-    if (!detector.records_manager_.texts_queued_for_paint_time_.empty()) {
-      detector.ReportSwapTime(WebWidgetClient::SwapResult::kDidSwap,
-                              CurrentTimeTicks());
+    if (detector &&
+        !detector->records_manager_.texts_queued_for_paint_time_.empty()) {
+      detector->ReportSwapTime(WebWidgetClient::SwapResult::kDidSwap,
+                               CurrentTimeTicks());
     }
   }
 
   size_t CountPendingSwapTime(LocalFrameView& frame_view) {
-    TextPaintTimingDetector& detector =
+    TextPaintTimingDetector* detector =
         frame_view.GetPaintTimingDetector().GetTextPaintTimingDetector();
-    return detector.records_manager_.texts_queued_for_paint_time_.size();
+    return detector->records_manager_.texts_queued_for_paint_time_.size();
   }
 
   void ChildFrameSwapTimeCallBack() {
     GetChildFrameView()
         .GetPaintTimingDetector()
         .GetTextPaintTimingDetector()
-        .ReportSwapTime(WebWidgetClient::SwapResult::kDidSwap,
-                        CurrentTimeTicks());
+        ->ReportSwapTime(WebWidgetClient::SwapResult::kDidSwap,
+                         CurrentTimeTicks());
   }
 
   void UpdateCandidate() {
-    GetPaintTimingDetector().GetTextPaintTimingDetector().UpdateCandidate();
+    GetPaintTimingDetector().GetTextPaintTimingDetector()->UpdateCandidate();
   }
 
   Element* AppendFontElementToBody(String content) {
@@ -129,14 +133,14 @@
     return GetFrameView()
         .GetPaintTimingDetector()
         .GetTextPaintTimingDetector()
-        .FindLargestPaintCandidate();
+        ->FindLargestPaintCandidate();
   }
 
   TextRecord* ChildFrameTextRecordOfLargestTextPaint() {
     return GetChildFrameView()
         .GetPaintTimingDetector()
         .GetTextPaintTimingDetector()
-        .FindLargestPaintCandidate();
+        ->FindLargestPaintCandidate();
   }
 
   void SetFontSize(Element* font_element, uint16_t font_size) {
@@ -428,11 +432,12 @@
 
   AppendDivElementToBody(WTF::String::Number(5000));
   UpdateAllLifecyclePhasesAndSimulateSwapTime();
-  EXPECT_EQ(CountVisibleTexts(), 5000u);
+  // Reached limit, so stopped recording and now should have 0 texts.
+  EXPECT_EQ(CountVisibleTexts(), 0u);
 
   AppendDivElementToBody(WTF::String::Number(5001));
   UpdateAllLifecyclePhasesAndSimulateSwapTime();
-  EXPECT_EQ(CountVisibleTexts(), 5000u);
+  EXPECT_EQ(CountVisibleTexts(), 0u);
 }
 
 // This is for comparison with the ClippedByViewport test.
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 6b3a22a..4fc938a 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -2100,10 +2100,12 @@
 #if defined(OS_MACOSX)
   return OutlineWidth();
 #else
+  if (LayoutTheme::GetTheme().IsFocusRingOutset()) {
+    return OutlineWidth();
+  }
   // Draw an outline with thickness in proportion to the zoom level, but never
   // so narrow that it becomes invisible.
-  return std::max(EffectiveZoom(),
-                  LayoutTheme::GetTheme().MinimumStrokeWidthForFocusRing());
+  return std::max(EffectiveZoom(), 1.f);
 #endif
 }
 
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc
index fda48d5..59247d5 100644
--- a/third_party/blink/renderer/core/style/computed_style_test.cc
+++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -78,26 +78,6 @@
 #endif
 }
 
-TEST(ComputedStyleTest, FocusRingCustomizedOutset) {
-  float old_minimum_stroke_width_for_focus_ring =
-      LayoutTheme::GetTheme().MinimumStrokeWidthForFocusRing();
-  bool old_is_focus_ring_outset = LayoutTheme::GetTheme().IsFocusRingOutset();
-  LayoutTheme::GetTheme().SetMinimumStrokeWidthForFocusRing(4.0);
-  LayoutTheme::GetTheme().SetIsFocusRingOutset(true);
-  scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
-  style->SetOutlineStyle(EBorderStyle::kSolid);
-  style->SetOutlineStyleIsAuto(static_cast<bool>(OutlineIsAuto::kOn));
-  style->SetEffectiveZoom(4.75);
-#if defined(OS_MACOSX)
-  EXPECT_EQ(4, style->OutlineOutsetExtent());
-#else
-  EXPECT_EQ(5, style->OutlineOutsetExtent());
-#endif
-  LayoutTheme::GetTheme().SetMinimumStrokeWidthForFocusRing(
-      old_minimum_stroke_width_for_focus_ring);
-  LayoutTheme::GetTheme().SetIsFocusRingOutset(old_is_focus_ring_outset);
-}
-
 TEST(ComputedStyleTest, SVGStackingContext) {
   scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
   style->UpdateIsStackingContext(false, false, true);
diff --git a/third_party/blink/renderer/core/timing/performance_timing.cc b/third_party/blink/renderer/core/timing/performance_timing.cc
index 32017d2c..7f59574 100644
--- a/third_party/blink/renderer/core/timing/performance_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_timing.cc
@@ -366,7 +366,7 @@
     return 0;
 
   return MonotonicTimeToIntegerMilliseconds(
-      paint_timing_detector->GetImagePaintTimingDetector().LargestImagePaint());
+      paint_timing_detector->LargestImagePaint());
 }
 
 uint64_t PerformanceTiming::LargestImagePaintSize() const {
@@ -374,8 +374,7 @@
   if (!paint_timing_detector)
     return 0;
 
-  return paint_timing_detector->GetImagePaintTimingDetector()
-      .LargestImagePaintSize();
+  return paint_timing_detector->LargestImagePaintSize();
 }
 
 uint64_t PerformanceTiming::LargestTextPaint() const {
@@ -384,7 +383,7 @@
     return 0;
 
   return MonotonicTimeToIntegerMilliseconds(
-      paint_timing_detector->GetTextPaintTimingDetector().LargestTextPaint());
+      paint_timing_detector->LargestTextPaint());
 }
 
 uint64_t PerformanceTiming::LargestTextPaintSize() const {
@@ -392,8 +391,7 @@
   if (!paint_timing_detector)
     return 0;
 
-  return paint_timing_detector->GetTextPaintTimingDetector()
-      .LargestTextPaintSize();
+  return paint_timing_detector->LargestTextPaintSize();
 }
 
 uint64_t PerformanceTiming::PageInteractive() const {
diff --git a/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js b/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js
index 05a162b..40faebd 100644
--- a/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js
+++ b/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js
@@ -55,14 +55,6 @@
     this._applicationTreeElement.appendChild(this.serviceWorkersTreeElement);
     const clearStorageTreeElement = new Resources.ClearStorageTreeElement(panel);
     this._applicationTreeElement.appendChild(clearStorageTreeElement);
-    if (Runtime.experiments.isEnabled('backgroundServices')) {
-      this.backgroundFetchTreeElement =
-          new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.BackgroundFetch);
-      this._applicationTreeElement.appendChild(this.backgroundFetchTreeElement);
-      this.backgroundSyncTreeElement =
-          new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.BackgroundSync);
-      this._applicationTreeElement.appendChild(this.backgroundSyncTreeElement);
-    }
 
     const storageTreeElement = this._addSidebarSection(Common.UIString('Storage'));
     this.localStorageListTreeElement =
@@ -112,6 +104,17 @@
 
     cacheTreeElement.appendChild(this.applicationCacheListTreeElement);
 
+    if (Runtime.experiments.isEnabled('backgroundServices')) {
+      const backgroundServiceTreeElement = this._addSidebarSection(ls`Background Services`);
+
+      this.backgroundFetchTreeElement =
+          new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.BackgroundFetch);
+      backgroundServiceTreeElement.appendChild(this.backgroundFetchTreeElement);
+      this.backgroundSyncTreeElement =
+          new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.BackgroundSync);
+      backgroundServiceTreeElement.appendChild(this.backgroundSyncTreeElement);
+    }
+
     this._resourcesSection = new Resources.ResourcesSection(panel, this._addSidebarSection(Common.UIString('Frames')));
 
     /** @type {!Map.<!Resources.Database, !Object.<string, !Resources.DatabaseTableView>>} */
diff --git a/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc b/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
index 4e6839e..691d58d 100644
--- a/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
+++ b/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
@@ -21,7 +21,7 @@
 void InstalledAppController::GetInstalledRelatedApps(
     std::unique_ptr<AppInstalledCallbacks> callbacks) {
   // When detached, the fetch logic is no longer valid.
-  if (context_destroyed_) {
+  if (!GetExecutionContext()) {
     // TODO(mgiuca): AbortError rather than simply undefined.
     // https://crbug.com/687846
     callbacks->OnError();
@@ -56,7 +56,6 @@
 
 void InstalledAppController::ContextDestroyed(ExecutionContext*) {
   provider_.reset();
-  context_destroyed_ = true;
 }
 
 void InstalledAppController::OnGetManifestForRelatedApps(
diff --git a/third_party/blink/renderer/modules/installedapp/installed_app_controller.h b/third_party/blink/renderer/modules/installedapp/installed_app_controller.h
index 3e3a5c0..80e1369 100644
--- a/third_party/blink/renderer/modules/installedapp/installed_app_controller.h
+++ b/third_party/blink/renderer/modules/installedapp/installed_app_controller.h
@@ -71,8 +71,6 @@
   // Handle to the InstalledApp mojo service.
   mojom::blink::InstalledAppProviderPtr provider_;
 
-  bool context_destroyed_ = false;
-
   DISALLOW_COPY_AND_ASSIGN(InstalledAppController);
 };
 
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
index 9b48647..af928e1 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
@@ -30,6 +30,7 @@
 #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h"
 #include "third_party/blink/renderer/modules/screen_orientation/web_lock_orientation_callback.h"
 #include "third_party/blink/renderer/platform/geometry/int_rect.h"
+#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/runtime_enabled_features_test_helpers.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -439,7 +440,7 @@
 }
 
 TEST_F(MediaControlsOrientationLockDelegateTest, DelegateRequiresVideo) {
-  HTMLAudioElement* audio = HTMLAudioElement::Create(GetDocument());
+  auto* audio = MakeGarbageCollected<HTMLAudioElement>(GetDocument());
   GetDocument().body()->AppendChild(audio);
   EXPECT_FALSE(HasDelegate(*audio->GetMediaControls()));
 }
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
index 5ff1999..677d266 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
@@ -28,6 +28,7 @@
 #include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
 #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
 #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h"
+#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/runtime_enabled_features_test_helpers.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -250,7 +251,7 @@
 }
 
 TEST_F(MediaControlsRotateToFullscreenDelegateTest, DelegateRequiresVideo) {
-  HTMLAudioElement* audio = HTMLAudioElement::Create(GetDocument());
+  auto* audio = MakeGarbageCollected<HTMLAudioElement>(GetDocument());
   GetDocument().body()->AppendChild(audio);
   EXPECT_FALSE(HasDelegate(*audio->GetMediaControls()));
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
index 785627d1..b2a9658 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
@@ -490,6 +490,13 @@
 }
 
 void RTCIceTransport::OnStateChanged(webrtc::IceTransportState new_state) {
+  // MONKEY PATCH:
+  // Due to crbug.com/957487, the lower layers signal kFailed when they
+  // should have been sending kDisconnected. Remap the state.
+  if (new_state == webrtc::IceTransportState::kFailed) {
+    LOG(INFO) << "crbug/957487: Remapping ICE state failed to disconnected";
+    new_state = webrtc::IceTransportState::kDisconnected;
+  }
   if (new_state == state_) {
     return;
   }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc
index 9e75208b..7f0ef42 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc
@@ -431,9 +431,13 @@
   ASSERT_TRUE(delegate);
 
   Persistent<MockEventListener> event_listener = CreateMockEventListener();
+  // Due to the quick fix for crbug.com/957487 (should go to "disconnected"
+  // state when end-of-candidates is signalled), this is accepting
+  // that the end state is 'disconnected' rather than 'failed'.
   EXPECT_CALL(*event_listener, Invoke(_, _))
-      .WillOnce(InvokeWithoutArgs(
-          [ice_transport] { EXPECT_EQ("failed", ice_transport->state()); }));
+      .WillOnce(InvokeWithoutArgs([ice_transport] {
+        EXPECT_EQ("disconnected", ice_transport->state());
+      }));
   ice_transport->addEventListener(event_type_names::kStatechange,
                                   event_listener);
 
@@ -539,8 +543,10 @@
 // Test that receiving an OnStateChange callback to the failed state once a
 // connection has been established clears the selected candidate pair without
 // firing the selectedcandidatepairchange event.
+// Disabled while sorting out the use of "failed" vs "disconnected"
+// (crbug.com/957847).
 TEST_F(RTCIceTransportTest,
-       OnStateChangeFailedAfterConnectedClearsSelectedCandidatePair) {
+       DISABLED_OnStateChangeFailedAfterConnectedClearsSelectedCandidatePair) {
   V8TestingScope scope;
 
   IceTransportAdapter::Delegate* delegate = nullptr;
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
index 629874a27..1ea4de8 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
+++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/core/testing/wait_for_event.h"
+#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"
 
@@ -128,7 +129,7 @@
         WTF::BindRepeating(&MockPictureInPictureService::Bind,
                            WTF::Unretained(&mock_service_)));
 
-    video_ = HTMLVideoElement::Create(GetDocument());
+    video_ = MakeGarbageCollected<HTMLVideoElement>(GetDocument());
     video_->SetReadyState(HTMLMediaElement::ReadyState::kHaveMetadata);
     layer_ = cc::Layer::Create();
     video_->SetCcLayerForTesting(layer_.get());
diff --git a/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc b/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
index 6211969..f40385e 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
@@ -99,31 +99,37 @@
   listening_status->last_known_availability = availability;
 
   std::vector<AvailabilityListener*> modified_listeners;
-  for (auto& listener : availability_listeners_) {
-    if (!listener->urls.Contains<KURL>(url))
-      continue;
+  {
+    // Set |iterating_listeners_| so we know not to allow modifications
+    // to |availability_listeners_|.
+    base::AutoReset<bool> iterating(&iterating_listeners_, true);
+    for (auto& listener_ref : availability_listeners_) {
+      auto* listener = listener_ref.get();
+      if (!listener->urls.Contains<KURL>(url))
+        continue;
 
-    auto screen_availability = GetScreenAvailability(listener->urls);
-    DCHECK(screen_availability != mojom::blink::ScreenAvailability::UNKNOWN);
-    for (auto* observer : listener->availability_observers)
-      observer->AvailabilityChanged(screen_availability);
+      auto screen_availability = GetScreenAvailability(listener->urls);
+      DCHECK(screen_availability != mojom::blink::ScreenAvailability::UNKNOWN);
+      for (auto* observer : listener->availability_observers)
+        observer->AvailabilityChanged(screen_availability);
 
-    if (screen_availability == mojom::blink::ScreenAvailability::DISABLED) {
-      for (auto& callback_ptr : listener->availability_callbacks) {
-        callback_ptr->RejectAvailabilityNotSupported();
+      if (screen_availability == mojom::blink::ScreenAvailability::DISABLED) {
+        for (auto& callback_ptr : listener->availability_callbacks) {
+          callback_ptr->RejectAvailabilityNotSupported();
+        }
+      } else {
+        for (auto& callback_ptr : listener->availability_callbacks) {
+          callback_ptr->Resolve(screen_availability ==
+                                mojom::blink::ScreenAvailability::AVAILABLE);
+        }
       }
-    } else {
-      for (auto& callback_ptr : listener->availability_callbacks) {
-        callback_ptr->Resolve(screen_availability ==
-                              mojom::blink::ScreenAvailability::AVAILABLE);
-      }
+      listener->availability_callbacks.clear();
+
+      for (const auto& availability_url : listener->urls)
+        MaybeStopListeningToURL(availability_url);
+
+      modified_listeners.push_back(listener);
     }
-    listener->availability_callbacks.clear();
-
-    for (const auto& availability_url : listener->urls)
-      MaybeStopListeningToURL(availability_url);
-
-    modified_listeners.push_back(listener.get());
   }
 
   for (auto* listener : modified_listeners)
@@ -222,6 +228,9 @@
 
 void PresentationAvailabilityState::TryRemoveAvailabilityListener(
     AvailabilityListener* listener) {
+  if (iterating_listeners_)
+    return;
+
   // URL is still observed by some availability object.
   if (!listener->availability_callbacks.empty() ||
       !listener->availability_observers.empty()) {
diff --git a/third_party/blink/renderer/modules/presentation/presentation_availability_state.h b/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
index e7b09d8..cbc58ab5 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
@@ -122,6 +122,10 @@
   // A pointer to PresentationService owned by PresentationController.
   mojom::blink::PresentationService* const presentation_service_;
 
+  // Whether we are iterating listeners, if this state is set we avoid
+  // removing items from |availability_listeners_|.
+  bool iterating_listeners_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(PresentationAvailabilityState);
 };
 
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 277254a..2bbf4f6a 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -134,6 +134,7 @@
   configs += [ "//third_party/blink/renderer:config" ]
   deps = [
     # Default manifest on Windows (a no-op elsewhere).
+    "//base",
     "//build/win:default_exe_manifest",
     "//third_party/icu",
   ]
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
index dc39104..2c5b963 100644
--- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -304,10 +304,6 @@
   RuntimeEnabledFeatures::SetOverscrollCustomizationEnabled(enable);
 }
 
-void WebRuntimeFeatures::EnablePageLifecycle(bool enable) {
-  RuntimeEnabledFeatures::SetPageLifecycleEnabled(enable);
-}
-
 void WebRuntimeFeatures::EnablePagePopup(bool enable) {
   RuntimeEnabledFeatures::SetPagePopupEnabled(enable);
 }
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
index 2d20fce..f1b75535 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -125,7 +125,7 @@
   if (mailbox.IsZero())
     return false;
 
-  *out_resource = viz::TransferableResource::MakeGLOverlay(
+  *out_resource = viz::TransferableResource::MakeGL(
       mailbox, GLFilter(), TextureTarget(), GetSyncToken(), gfx::Size(Size()),
       IsOverlayCandidate());
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
index 6543a73..d217c0b 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -3473,6 +3473,51 @@
   EXPECT_TRUE(cc_descendant_transform->in_subtree_of_page_scale_layer);
 }
 
+// Test that PaintArtifactCompositor pushes page scale to the transform tree.
+TEST_P(PaintArtifactCompositorTest, ViewportPageScale) {
+  // Create a page scale transform node with a page scale factor of 2.0.
+  TransformationMatrix matrix;
+  matrix.Scale(2);
+  TransformPaintPropertyNode::State transform_state{matrix};
+  transform_state.in_subtree_of_page_scale = false;
+  transform_state.compositor_element_id =
+      CompositorElementIdFromUniqueObjectId(1);
+  auto scale_transform_node = TransformPaintPropertyNode::Create(
+      TransformPaintPropertyNode::Root(), std::move(transform_state));
+
+  // Create a viewport scroll node with container size 20x10 and contents size
+  // 27x32.
+  ScrollPaintPropertyNode::State scroll_state;
+  scroll_state.container_rect = IntRect(5, 5, 20, 10);
+  scroll_state.contents_size = IntSize(27, 32);
+  scroll_state.user_scrollable_vertical = true;
+  scroll_state.max_scroll_offset_affected_by_page_scale = true;
+  scroll_state.compositor_element_id = ScrollElementId(2);
+
+  auto scroll =
+      CreateScroll(ScrollPaintPropertyNode::Root(), scroll_state,
+                   kNotScrollingOnMain, scroll_state.compositor_element_id);
+  auto scroll_translation =
+      CreateScrollTranslation(*scale_transform_node, 0, 0, *scroll);
+
+  TestPaintArtifact artifact;
+  artifact.Chunk(*scroll_translation, c0(), e0())
+      .RectDrawing(FloatRect(0, 0, 10, 10), Color::kBlack);
+  ViewportProperties viewport_properties;
+  viewport_properties.page_scale = scale_transform_node.get();
+  CompositorElementIdSet element_ids;
+  Update(artifact.Build(), element_ids, viewport_properties);
+
+  cc::ScrollTree& scroll_tree = GetPropertyTrees().scroll_tree;
+  cc::ScrollNode* cc_scroll_node =
+      scroll_tree.FindNodeFromElementId(scroll_state.compositor_element_id);
+  auto max_scroll_offset = scroll_tree.MaxScrollOffset(cc_scroll_node->id);
+  // The max scroll offset should be scaled by the page scale factor (see:
+  // |ScrollTree::MaxScrollOffset|). This adjustment scales the contents from
+  // 27x32 to 54x64 so the max scroll offset becomes (54-20)/2 x (64-10)/2.
+  EXPECT_EQ(gfx::ScrollOffset(17, 27), max_scroll_offset);
+}
+
 enum {
   kNoRenderSurface = 0,
   kHasRenderSurface = 1 << 0,
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index d6ee4d3..0ee35c24 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -174,6 +174,9 @@
   UpdateCcTransformLocalMatrix(*cc_transform, transform);
   AdjustPageScaleToUsePostLocal(*cc_transform);
   cc_transform->transform_changed = true;
+
+  SetTransformTreePageScaleFactor(&property_trees->transform_tree,
+                                  cc_transform);
   property_trees->transform_tree.set_needs_update(true);
   return true;
 }
@@ -479,6 +482,8 @@
   cc::TransformNode& compositor_node = *GetTransformTree().Node(id);
   AdjustPageScaleToUsePostLocal(compositor_node);
   compositor_node.transform_changed = true;
+
+  SetTransformTreePageScaleFactor(&GetTransformTree(), &compositor_node);
   GetTransformTree().set_needs_update(true);
   return id;
 }
@@ -495,6 +500,20 @@
   page_scale.local.matrix().setIdentity();
 }
 
+void PropertyTreeManager::SetTransformTreePageScaleFactor(
+    cc::TransformTree* transform_tree,
+    cc::TransformNode* page_scale_node) {
+  // |AdjustPageScaleToUsePostLocal| should have been called already so that the
+  // scale component is in the post_local transform.
+  DCHECK(page_scale_node->local.IsIdentity());
+  DCHECK(page_scale_node->pre_local.IsIdentity());
+
+  DCHECK(page_scale_node->post_local.IsScale2d());
+  auto page_scale = page_scale_node->post_local.Scale2d();
+  DCHECK_EQ(page_scale.x(), page_scale.y());
+  transform_tree->set_page_scale_factor(page_scale.x());
+}
+
 int PropertyTreeManager::EnsureCompositorClipNode(
     const ClipPaintPropertyNode& clip_node_arg) {
   const auto& clip_node = clip_node_arg.Unalias();
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
index 6eb8ada0..807028b 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
@@ -161,6 +161,10 @@
   // compositor has an assumption that the page scale is in the post_local
   // matrix but |UpdateCcTransformLocalMatrix| uses the local matrix.
   void AdjustPageScaleToUsePostLocal(cc::TransformNode&);
+  // Sets |cc::TransformNode::page_scale_factor_| from the scale in the page
+  // scale node.
+  void SetTransformTreePageScaleFactor(cc::TransformTree*,
+                                       cc::TransformNode* page_scale_node);
   // Move the local translation into the scroll_offset field of the compositor
   // transform node. The compositor uses a speical scroll_offset field instead
   // of the local matrix for scroll nodes, whereas
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
index 79d784a..5bb0bd9 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -464,7 +464,7 @@
   // Populate the output mailbox and callback.
   {
     bool is_overlay_candidate = !!color_buffer_for_mailbox->gpu_memory_buffer;
-    *out_resource = viz::TransferableResource::MakeGLOverlay(
+    *out_resource = viz::TransferableResource::MakeGL(
         color_buffer_for_mailbox->mailbox, GL_LINEAR, texture_target_,
         color_buffer_for_mailbox->produce_sync_token, gfx::Size(size_),
         is_overlay_candidate);
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
index a0aa6435..acf73ec 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -116,12 +116,15 @@
     if (!image_for_compositor)
       return false;
 
+    const gfx::Size size(image_for_compositor->width(),
+                         image_for_compositor->height());
     uint32_t filter =
         filter_quality_ == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR;
     image_for_compositor->EnsureMailbox(kUnverifiedSyncToken, filter);
     *out_resource = viz::TransferableResource::MakeGL(
         image_for_compositor->GetMailbox(), filter, GL_TEXTURE_2D,
-        image_for_compositor->GetSyncToken());
+        image_for_compositor->GetSyncToken(), size,
+        false /* is_overlay_candidate */);
     auto func =
         WTF::Bind(&ImageLayerBridge::ResourceReleasedGpu,
                   WrapWeakPersistent(this), std::move(image_for_compositor));
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
index 39789d5..5e6ff9a 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
@@ -137,7 +137,7 @@
       current_swap_buffer_->access_finished_token.GetData());
 
   // Populate the output resource
-  *out_resource = viz::TransferableResource::MakeGLOverlay(
+  *out_resource = viz::TransferableResource::MakeGL(
       current_swap_buffer_->mailbox, GL_LINEAR, GL_TEXTURE_RECTANGLE_ARB,
       current_swap_buffer_->access_finished_token, current_swap_buffer_->size,
       false);
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc
index efe0bd83..e7ede40 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -407,11 +407,11 @@
   DrawFocusRingPath(focus_ring_path.GetSkPath(), color, width);
 }
 
-void GraphicsContext::DrawFocusRing(const Vector<IntRect>& rects,
-                                    float width,
-                                    int offset,
-                                    const Color& color,
-                                    bool is_outset) {
+void GraphicsContext::DrawFocusRingInternal(const Vector<IntRect>& rects,
+                                            float width,
+                                            int offset,
+                                            const Color& color,
+                                            bool is_outset) {
   if (ContextDisabled())
     return;
 
@@ -442,6 +442,45 @@
   }
 }
 
+namespace {
+
+static const double kFocusRingLuminanceThreshold = 0.45;
+
+bool ShouldDrawInnerFocusRingForContrast(bool is_outset,
+                                         float width,
+                                         Color color) {
+  if (!is_outset || width < 3) {
+    return false;
+  }
+  double h = 0.0, s = 0.0, l = 0.0;
+  color.GetHSL(h, s, l);
+  return l < kFocusRingLuminanceThreshold;
+}
+
+}  // namespace
+
+void GraphicsContext::DrawFocusRing(const Vector<IntRect>& rects,
+                                    float width,
+                                    int offset,
+                                    const Color& color,
+                                    bool is_outset) {
+  // If a focus ring is outset and the color is dark, it may be hard to see on
+  // dark backgrounds. In this case, we'll actually draw two focus rings, the
+  // outset focus ring with a white inner ring for contrast.
+  if (ShouldDrawInnerFocusRingForContrast(is_outset, width, color)) {
+    int contrast_offset = static_cast<int>(std::floor(width * 0.5));
+    // We create a 1px gap for the contrast ring. The contrast ring is drawn
+    // first, and we overdraw by a pixel to ensure no gaps or AA artifacts.
+    DrawFocusRingInternal(rects, contrast_offset, offset, SK_ColorWHITE,
+                          is_outset);
+    DrawFocusRingInternal(rects, width - contrast_offset,
+                          offset + contrast_offset, color, is_outset);
+
+  } else {
+    DrawFocusRingInternal(rects, width, offset, color, is_outset);
+  }
+}
+
 static inline FloatRect AreaCastingShadowInHole(
     const FloatRect& hole_rect,
     float shadow_blur,
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.h b/third_party/blink/renderer/platform/graphics/graphics_context.h
index dd46da0..396b7b1 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.h
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -428,6 +428,12 @@
   void DrawFocusRingPath(const SkPath&, const Color&, float width);
   void DrawFocusRingRect(const SkRect&, const Color&, float width);
 
+  void DrawFocusRingInternal(const Vector<IntRect>&,
+                             float width,
+                             int offset,
+                             const Color&,
+                             bool is_outset);
+
   // SkCanvas wrappers.
   void ClipRRect(const SkRRect&,
                  AntiAliasingMode = kNotAntiAliased,
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
index 706c6e0..61fc64f 100644
--- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
@@ -114,13 +114,26 @@
   // Check for accumulated clip rect change, if the clip rects are tight.
   if (new_chunk_info.chunk_to_layer_clip.IsTight() &&
       old_chunk_info.chunk_to_layer_clip.IsTight()) {
-    if (new_chunk_info.chunk_to_layer_clip ==
-        old_chunk_info.chunk_to_layer_clip)
+    const auto& new_clip_rect = new_chunk_info.chunk_to_layer_clip.Rect();
+    const auto& old_clip_rect = old_chunk_info.chunk_to_layer_clip.Rect();
+    if (new_clip_rect == old_clip_rect)
       return PaintInvalidationReason::kNone;
     // Ignore differences out of the current layer bounds.
-    if (ClipByLayerBounds(new_chunk_info.chunk_to_layer_clip.Rect()) ==
-        ClipByLayerBounds(old_chunk_info.chunk_to_layer_clip.Rect()))
+    auto new_clip_in_layer_bounds = ClipByLayerBounds(new_clip_rect);
+    auto old_clip_in_layer_bounds = ClipByLayerBounds(old_clip_rect);
+    if (new_clip_in_layer_bounds == old_clip_in_layer_bounds)
       return PaintInvalidationReason::kNone;
+
+    // Clip changed and may have visual effect, so we need raster invalidation.
+    if (!new_clip_in_layer_bounds.Contains(new_chunk_info.bounds_in_layer) ||
+        !old_clip_in_layer_bounds.Contains(old_chunk_info.bounds_in_layer)) {
+      // If the chunk is not fully covered by the clip rect, we have to do full
+      // invalidation instead of incremental because the delta parts of the
+      // layer bounds may not cover all changes caused by the clip change.
+      // This can happen because of pixel snapping, raster effect outset, etc.
+      return PaintInvalidationReason::kPaintProperty;
+    }
+    // Otherwise we just invalidate the delta parts of the layer bounds.
     return PaintInvalidationReason::kIncremental;
   }
 
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
index 08cc153..6d8f3913 100644
--- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
@@ -389,6 +389,40 @@
   FinishCycle(*artifact);
 }
 
+// Tests the path detecting change of PaintChunkInfo::chunk_to_layer_clip.
+// The chunk bounds is bigger than the clip because of the outset for raster
+// effects, so incremental invalidation is not suitable.
+TEST_P(RasterInvalidatorTest, ClipPropertyChangeWithOutsetForRasterEffects) {
+  FloatRoundedRect clip_rect(-1000, -1000, 2000, 2000);
+  auto clip = CreateClip(c0(), t0(), clip_rect);
+
+  PropertyTreeState layer_state = PropertyTreeState::Root();
+  auto artifact = TestPaintArtifact()
+                      .Chunk(0)
+                      .Properties(t0(), *clip, e0())
+                      .Bounds(EnclosingIntRect(clip_rect.Rect()))
+                      .OutsetForRasterEffects(2)
+                      .Build();
+
+  invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+  FinishCycle(*artifact);
+
+  invalidator_.SetTracksRasterInvalidations(true);
+  FloatRoundedRect new_clip_rect(-2000, -2000, 4000, 4000);
+  clip->Update(c0(), ClipPaintPropertyNode::State{&t0(), new_clip_rect});
+
+  invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+  const auto& invalidations = TrackedRasterInvalidations();
+  ASSERT_EQ(1u, invalidations.size());
+  auto mapper = [](IntRect& r) { r.Inflate(2); };
+  EXPECT_CHUNK_INVALIDATION_CUSTOM(invalidations, 0, artifact->PaintChunks()[0],
+                                   PaintInvalidationReason::kPaintProperty,
+                                   -kDefaultLayerBounds.Location(),
+                                   base::BindRepeating(mapper));
+  invalidator_.SetTracksRasterInvalidations(false);
+  FinishCycle(*artifact);
+}
+
 TEST_P(RasterInvalidatorTest, ClipLocalTransformSpaceChange) {
   auto t1 = CreateTransform(t0(), TransformationMatrix());
   auto t2 = CreateTransform(*t1, TransformationMatrix());
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn
index 31f54f4..ef6e26b2 100644
--- a/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -117,6 +117,7 @@
     "object_start_bitmap_test.cc",
     "persistent_test.cc",
     "run_all_tests.cc",
+    "sparse_heap_bitmap_test.cc",
     "thread_state_scheduling_test.cc",
     "worklist_test.cc",
   ]
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.cc b/third_party/blink/renderer/platform/heap/heap_compact.cc
index b579344..578ec57 100644
--- a/third_party/blink/renderer/platform/heap/heap_compact.cc
+++ b/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -51,6 +51,19 @@
     BasePage* const slot_page =
         heap_->LookupPageForAddress(reinterpret_cast<Address>(slot));
     CHECK(slot_page);
+    if (slot_page->IsLargeObjectPage()) {
+      CHECK(
+          static_cast<LargeObjectPage*>(slot_page)->ObjectHeader()->IsMarked());
+    } else {
+      HeapObjectHeader* const header =
+          static_cast<NormalPage*>(slot_page)->FindHeaderFromAddress(
+              reinterpret_cast<Address>(slot));
+      CHECK(header);
+      CHECK(slot_page->Arena()->ArenaIndex() ==
+                BlinkGC::kEagerSweepArenaIndex ||
+            header->IsMarked());
+    }
+
     BasePage* const value_page =
         heap_->LookupPageForAddress(reinterpret_cast<Address>(value));
     CHECK(value_page);
@@ -62,6 +75,18 @@
         !HeapCompact::IsCompactableArena(value_page->Arena()->ArenaIndex()))
       return;
 
+    // Slots must reside in and values must point to live objects at this
+    // point, with the exception of slots in eagerly swept arenas where objects
+    // have already been processed. |value| usually points to a separate
+    // backing store but can also point to inlined storage which is why the
+    // dynamic header lookup is required.
+    CHECK(value_page->Arena()->ArenaIndex() != BlinkGC::kEagerSweepArenaIndex);
+    HeapObjectHeader* const value_header =
+        static_cast<NormalPage*>(value_page)
+            ->FindHeaderFromAddress(reinterpret_cast<Address>(value));
+    CHECK(value_header);
+    CHECK(value_header->IsMarked());
+
     // Slots may have been recorded already but must point to the same
     // value. Example: Ephemeron iterations may register slots multiple
     // times.
@@ -77,26 +102,6 @@
     // Add regular fixup.
     fixups_.insert({value, slot});
 
-    // Slots must reside in and values must point to live objects at this
-    // point, with the exception of slots in eagerly swept arenas where objects
-    // have already been processed. |value| usually points to a separate
-    // backing store but can also point to inlined storage which is why the
-    // dynamic header lookup is required.
-    CHECK(value_page->Arena()->ArenaIndex() != BlinkGC::kEagerSweepArenaIndex);
-    CHECK(static_cast<NormalPage*>(value_page)
-              ->FindHeaderFromAddress(reinterpret_cast<Address>(value))
-              ->IsMarked());
-    if (slot_page->IsLargeObjectPage()) {
-      CHECK(
-          static_cast<LargeObjectPage*>(slot_page)->ObjectHeader()->IsMarked());
-    } else {
-      CHECK(slot_page->Arena()->ArenaIndex() ==
-                BlinkGC::kEagerSweepArenaIndex ||
-            static_cast<NormalPage*>(slot_page)
-                ->FindHeaderFromAddress(reinterpret_cast<Address>(slot))
-                ->IsMarked());
-    }
-
     // Check whether the slot itself resides on a page that is compacted.
     if (LIKELY(!relocatable_pages_.Contains(slot_page)))
       return;
diff --git a/third_party/blink/renderer/platform/heap/heap_compact_test.cc b/third_party/blink/renderer/platform/heap/heap_compact_test.cc
index 462218a..3cb93045 100644
--- a/third_party/blink/renderer/platform/heap/heap_compact_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_compact_test.cc
@@ -95,143 +95,6 @@
 
 namespace blink {
 
-static const size_t kChunkRange = SparseHeapBitmap::kBitmapChunkRange;
-static const size_t kUnitPointer = 0x1u
-                                   << SparseHeapBitmap::kPointerAlignmentInBits;
-
-TEST(HeapCompactTest, SparseBitmapBasic) {
-  Address base = reinterpret_cast<Address>(0x10000u);
-  auto bitmap = std::make_unique<SparseHeapBitmap>(base);
-
-  size_t double_chunk = 2 * kChunkRange;
-
-  // 101010... starting at |base|.
-  for (size_t i = 0; i < double_chunk; i += 2 * kUnitPointer)
-    bitmap->Add(base + i);
-
-  // Check that hasRange() returns a bitmap subtree, if any, for a given
-  // address.
-  EXPECT_TRUE(!!bitmap->HasRange(base, 1));
-  EXPECT_TRUE(!!bitmap->HasRange(base + kUnitPointer, 1));
-  EXPECT_FALSE(!!bitmap->HasRange(base - kUnitPointer, 1));
-
-  // Test implementation details.. that each SparseHeapBitmap node maps
-  // |s_bitmapChunkRange| ranges only.
-  EXPECT_EQ(bitmap->HasRange(base + kUnitPointer, 1),
-            bitmap->HasRange(base + 2 * kUnitPointer, 1));
-  // Second range will be just past the first.
-  EXPECT_NE(bitmap->HasRange(base, 1), bitmap->HasRange(base + kChunkRange, 1));
-
-  // Iterate a range that will encompass more than one 'chunk'.
-  SparseHeapBitmap* start =
-      bitmap->HasRange(base + 2 * kUnitPointer, double_chunk);
-  EXPECT_TRUE(!!start);
-  for (size_t i = 2 * kUnitPointer; i < double_chunk; i += 2 * kUnitPointer) {
-    EXPECT_TRUE(start->IsSet(base + i));
-    EXPECT_FALSE(start->IsSet(base + i + kUnitPointer));
-  }
-}
-
-TEST(HeapCompactTest, SparseBitmapBuild) {
-  Address base = reinterpret_cast<Address>(0x10000u);
-  auto bitmap = std::make_unique<SparseHeapBitmap>(base);
-
-  size_t double_chunk = 2 * kChunkRange;
-
-  // Create a sparse bitmap containing at least three chunks.
-  bitmap->Add(base - double_chunk);
-  bitmap->Add(base + double_chunk);
-
-  // This is sanity testing internal implementation details of
-  // SparseHeapBitmap; probing |isSet()| outside the bitmap
-  // of the range used in |hasRange()|, is not defined.
-  //
-  // Regardless, the testing here verifies that a |hasRange()| that
-  // straddles multiple internal nodes, returns a bitmap that is
-  // capable of returning correct |isSet()| results.
-  SparseHeapBitmap* start = bitmap->HasRange(
-      base - double_chunk - 2 * kUnitPointer, 4 * kUnitPointer);
-  EXPECT_TRUE(!!start);
-  EXPECT_TRUE(start->IsSet(base - double_chunk));
-  EXPECT_FALSE(start->IsSet(base - double_chunk + kUnitPointer));
-  EXPECT_FALSE(start->IsSet(base));
-  EXPECT_FALSE(start->IsSet(base + kUnitPointer));
-  EXPECT_FALSE(start->IsSet(base + double_chunk));
-  EXPECT_FALSE(start->IsSet(base + double_chunk + kUnitPointer));
-
-  start = bitmap->HasRange(base - double_chunk - 2 * kUnitPointer,
-                           2 * double_chunk + 2 * kUnitPointer);
-  EXPECT_TRUE(!!start);
-  EXPECT_TRUE(start->IsSet(base - double_chunk));
-  EXPECT_FALSE(start->IsSet(base - double_chunk + kUnitPointer));
-  EXPECT_TRUE(start->IsSet(base));
-  EXPECT_FALSE(start->IsSet(base + kUnitPointer));
-  EXPECT_TRUE(start->IsSet(base + double_chunk));
-  EXPECT_FALSE(start->IsSet(base + double_chunk + kUnitPointer));
-
-  start = bitmap->HasRange(base, 20);
-  EXPECT_TRUE(!!start);
-  // Probing for values outside of hasRange() should be considered
-  // undefined, but do it to exercise the (left) tree traversal.
-  EXPECT_TRUE(start->IsSet(base - double_chunk));
-  EXPECT_FALSE(start->IsSet(base - double_chunk + kUnitPointer));
-  EXPECT_TRUE(start->IsSet(base));
-  EXPECT_FALSE(start->IsSet(base + kUnitPointer));
-  EXPECT_TRUE(start->IsSet(base + double_chunk));
-  EXPECT_FALSE(start->IsSet(base + double_chunk + kUnitPointer));
-
-  start = bitmap->HasRange(base + kChunkRange + 2 * kUnitPointer, 2048);
-  EXPECT_TRUE(!!start);
-  // Probing for values outside of hasRange() should be considered
-  // undefined, but do it to exercise node traversal.
-  EXPECT_FALSE(start->IsSet(base - double_chunk));
-  EXPECT_FALSE(start->IsSet(base - double_chunk + kUnitPointer));
-  EXPECT_FALSE(start->IsSet(base));
-  EXPECT_FALSE(start->IsSet(base + kUnitPointer));
-  EXPECT_FALSE(start->IsSet(base + kChunkRange));
-  EXPECT_TRUE(start->IsSet(base + double_chunk));
-  EXPECT_FALSE(start->IsSet(base + double_chunk + kUnitPointer));
-}
-
-TEST(HeapCompactTest, SparseBitmapLeftExtension) {
-  Address base = reinterpret_cast<Address>(0x10000u);
-  auto bitmap = std::make_unique<SparseHeapBitmap>(base);
-
-  SparseHeapBitmap* start = bitmap->HasRange(base, 1);
-  EXPECT_TRUE(start);
-
-  // Verify that re-adding is a no-op.
-  bitmap->Add(base);
-  EXPECT_EQ(start, bitmap->HasRange(base, 1));
-
-  // Adding an Address |A| before a single-address SparseHeapBitmap node should
-  // cause that node to  be "left extended" to use |A| as its new base.
-  bitmap->Add(base - 2 * kUnitPointer);
-  EXPECT_EQ(bitmap->HasRange(base, 1),
-            bitmap->HasRange(base - 2 * kUnitPointer, 1));
-
-  // Reset.
-  bitmap = std::make_unique<SparseHeapBitmap>(base);
-
-  // If attempting same as above, but the Address |A| is outside the
-  // chunk size of a node, a new SparseHeapBitmap node needs to be
-  // created to the left of |bitmap|.
-  bitmap->Add(base - kChunkRange);
-  EXPECT_NE(bitmap->HasRange(base, 1),
-            bitmap->HasRange(base - 2 * kUnitPointer, 1));
-
-  bitmap = std::make_unique<SparseHeapBitmap>(base);
-  bitmap->Add(base - kChunkRange + kUnitPointer);
-  // This address is just inside the horizon and shouldn't create a new chunk.
-  EXPECT_EQ(bitmap->HasRange(base, 1),
-            bitmap->HasRange(base - 2 * kUnitPointer, 1));
-  // ..but this one should, like for the sub-test above.
-  bitmap->Add(base - kChunkRange);
-  EXPECT_EQ(bitmap->HasRange(base, 1),
-            bitmap->HasRange(base - 2 * kUnitPointer, 1));
-  EXPECT_NE(bitmap->HasRange(base, 1), bitmap->HasRange(base - kChunkRange, 1));
-}
-
 static void PerformHeapCompaction() {
   EXPECT_FALSE(HeapCompact::ScheduleCompactionGCForTesting(true));
   PreciselyCollectGarbage();
diff --git a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
index 767cab6..bc021c11 100644
--- a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
+++ b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
@@ -1862,5 +1862,31 @@
   PreciselyCollectGarbage();
 }
 
+TEST(IncrementalMarkingTest, IncrementalMarkingShrinkingBackingCompaction) {
+  // Regression test: https://crbug.com/918064
+
+  using Nested = HeapVector<HeapVector<Member<Object>>>;
+  // The following setup will ensure that the outer HeapVector's backing store
+  // contains slots to other to-be-compacted backings.
+  Persistent<Nested> holder(MakeGarbageCollected<Nested>());
+  for (int i = 0; i < 32; i++) {
+    holder->emplace_back();
+    holder->at(i).emplace_back(MakeGarbageCollected<Object>());
+  }
+  IncrementalMarkingTestDriver driver(ThreadState::Current());
+  ThreadState::Current()->Heap().Compaction()->ScheduleCompactionGCForTesting(
+      true);
+  driver.Start();
+  driver.FinishSteps();
+  // Reduce size of the outer backing store.
+  for (int i = 0; i < 16; i++) {
+    holder->pop_back();
+  }
+  // Ensure that shrinking the backing does not crash in compaction as there may
+  // be registered slots left in the area that is already freed.
+  holder->ShrinkToFit();
+  driver.FinishGC();
+}
+
 }  // namespace incremental_marking_test
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/sparse_heap_bitmap_test.cc b/third_party/blink/renderer/platform/heap/sparse_heap_bitmap_test.cc
new file mode 100644
index 0000000..afc432c
--- /dev/null
+++ b/third_party/blink/renderer/platform/heap/sparse_heap_bitmap_test.cc
@@ -0,0 +1,152 @@
+// 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/platform/heap/sparse_heap_bitmap.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+namespace {
+
+constexpr size_t kChunkRange = SparseHeapBitmap::kBitmapChunkRange;
+constexpr size_t kUnitPointer = 0x1u
+                                << SparseHeapBitmap::kPointerAlignmentInBits;
+
+}  // namespace
+
+TEST(SparseHeapBitmapTest, SparseBitmapBasic) {
+  Address base = reinterpret_cast<Address>(0x10000u);
+  auto bitmap = std::make_unique<SparseHeapBitmap>(base);
+
+  size_t double_chunk = 2 * kChunkRange;
+
+  // 101010... starting at |base|.
+  for (size_t i = 0; i < double_chunk; i += 2 * kUnitPointer)
+    bitmap->Add(base + i);
+
+  // Check that hasRange() returns a bitmap subtree, if any, for a given
+  // address.
+  EXPECT_TRUE(!!bitmap->HasRange(base, 1));
+  EXPECT_TRUE(!!bitmap->HasRange(base + kUnitPointer, 1));
+  EXPECT_FALSE(!!bitmap->HasRange(base - kUnitPointer, 1));
+
+  // Test implementation details.. that each SparseHeapBitmap node maps
+  // |s_bitmapChunkRange| ranges only.
+  EXPECT_EQ(bitmap->HasRange(base + kUnitPointer, 1),
+            bitmap->HasRange(base + 2 * kUnitPointer, 1));
+  // Second range will be just past the first.
+  EXPECT_NE(bitmap->HasRange(base, 1), bitmap->HasRange(base + kChunkRange, 1));
+
+  // Iterate a range that will encompass more than one 'chunk'.
+  SparseHeapBitmap* start =
+      bitmap->HasRange(base + 2 * kUnitPointer, double_chunk);
+  EXPECT_TRUE(!!start);
+  for (size_t i = 2 * kUnitPointer; i < double_chunk; i += 2 * kUnitPointer) {
+    EXPECT_TRUE(start->IsSet(base + i));
+    EXPECT_FALSE(start->IsSet(base + i + kUnitPointer));
+  }
+}
+
+TEST(SparseHeapBitmapTest, SparseBitmapBuild) {
+  Address base = reinterpret_cast<Address>(0x10000u);
+  auto bitmap = std::make_unique<SparseHeapBitmap>(base);
+
+  size_t double_chunk = 2 * kChunkRange;
+
+  // Create a sparse bitmap containing at least three chunks.
+  bitmap->Add(base - double_chunk);
+  bitmap->Add(base + double_chunk);
+
+  // This is sanity testing internal implementation details of
+  // SparseHeapBitmap; probing |isSet()| outside the bitmap
+  // of the range used in |hasRange()|, is not defined.
+  //
+  // Regardless, the testing here verifies that a |hasRange()| that
+  // straddles multiple internal nodes, returns a bitmap that is
+  // capable of returning correct |isSet()| results.
+  SparseHeapBitmap* start = bitmap->HasRange(
+      base - double_chunk - 2 * kUnitPointer, 4 * kUnitPointer);
+  EXPECT_TRUE(!!start);
+  EXPECT_TRUE(start->IsSet(base - double_chunk));
+  EXPECT_FALSE(start->IsSet(base - double_chunk + kUnitPointer));
+  EXPECT_FALSE(start->IsSet(base));
+  EXPECT_FALSE(start->IsSet(base + kUnitPointer));
+  EXPECT_FALSE(start->IsSet(base + double_chunk));
+  EXPECT_FALSE(start->IsSet(base + double_chunk + kUnitPointer));
+
+  start = bitmap->HasRange(base - double_chunk - 2 * kUnitPointer,
+                           2 * double_chunk + 2 * kUnitPointer);
+  EXPECT_TRUE(!!start);
+  EXPECT_TRUE(start->IsSet(base - double_chunk));
+  EXPECT_FALSE(start->IsSet(base - double_chunk + kUnitPointer));
+  EXPECT_TRUE(start->IsSet(base));
+  EXPECT_FALSE(start->IsSet(base + kUnitPointer));
+  EXPECT_TRUE(start->IsSet(base + double_chunk));
+  EXPECT_FALSE(start->IsSet(base + double_chunk + kUnitPointer));
+
+  start = bitmap->HasRange(base, 20);
+  EXPECT_TRUE(!!start);
+  // Probing for values outside of hasRange() should be considered
+  // undefined, but do it to exercise the (left) tree traversal.
+  EXPECT_TRUE(start->IsSet(base - double_chunk));
+  EXPECT_FALSE(start->IsSet(base - double_chunk + kUnitPointer));
+  EXPECT_TRUE(start->IsSet(base));
+  EXPECT_FALSE(start->IsSet(base + kUnitPointer));
+  EXPECT_TRUE(start->IsSet(base + double_chunk));
+  EXPECT_FALSE(start->IsSet(base + double_chunk + kUnitPointer));
+
+  start = bitmap->HasRange(base + kChunkRange + 2 * kUnitPointer, 2048);
+  EXPECT_TRUE(!!start);
+  // Probing for values outside of hasRange() should be considered
+  // undefined, but do it to exercise node traversal.
+  EXPECT_FALSE(start->IsSet(base - double_chunk));
+  EXPECT_FALSE(start->IsSet(base - double_chunk + kUnitPointer));
+  EXPECT_FALSE(start->IsSet(base));
+  EXPECT_FALSE(start->IsSet(base + kUnitPointer));
+  EXPECT_FALSE(start->IsSet(base + kChunkRange));
+  EXPECT_TRUE(start->IsSet(base + double_chunk));
+  EXPECT_FALSE(start->IsSet(base + double_chunk + kUnitPointer));
+}
+
+TEST(SparseHeapBitmapTest, SparseBitmapLeftExtension) {
+  Address base = reinterpret_cast<Address>(0x10000u);
+  auto bitmap = std::make_unique<SparseHeapBitmap>(base);
+
+  SparseHeapBitmap* start = bitmap->HasRange(base, 1);
+  EXPECT_TRUE(start);
+
+  // Verify that re-adding is a no-op.
+  bitmap->Add(base);
+  EXPECT_EQ(start, bitmap->HasRange(base, 1));
+
+  // Adding an Address |A| before a single-address SparseHeapBitmap node should
+  // cause that node to  be "left extended" to use |A| as its new base.
+  bitmap->Add(base - 2 * kUnitPointer);
+  EXPECT_EQ(bitmap->HasRange(base, 1),
+            bitmap->HasRange(base - 2 * kUnitPointer, 1));
+
+  // Reset.
+  bitmap = std::make_unique<SparseHeapBitmap>(base);
+
+  // If attempting same as above, but the Address |A| is outside the
+  // chunk size of a node, a new SparseHeapBitmap node needs to be
+  // created to the left of |bitmap|.
+  bitmap->Add(base - kChunkRange);
+  EXPECT_NE(bitmap->HasRange(base, 1),
+            bitmap->HasRange(base - 2 * kUnitPointer, 1));
+
+  bitmap = std::make_unique<SparseHeapBitmap>(base);
+  bitmap->Add(base - kChunkRange + kUnitPointer);
+  // This address is just inside the horizon and shouldn't create a new chunk.
+  EXPECT_EQ(bitmap->HasRange(base, 1),
+            bitmap->HasRange(base - 2 * kUnitPointer, 1));
+  // ..but this one should, like for the sub-test above.
+  bitmap->Add(base - kChunkRange);
+  EXPECT_EQ(bitmap->HasRange(base, 1),
+            bitmap->HasRange(base - 2 * kUnitPointer, 1));
+  EXPECT_NE(bitmap->HasRange(base, 1), bitmap->HasRange(base - kChunkRange, 1));
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
index 40e5fff..14025593 100644
--- a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
+++ b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
@@ -735,8 +735,8 @@
     auto* xform = ColorTransform();
     auto* src_profile = xform ? xform->SrcProfile() : nullptr;
     auto* dst_profile = xform ? xform->DstProfile() : nullptr;
-    auto src_format = has_alpha ? skcms_PixelFormat_RGBA_16161616
-                                : skcms_PixelFormat_RGB_161616;
+    auto src_format = has_alpha ? skcms_PixelFormat_RGBA_16161616BE
+                                : skcms_PixelFormat_RGB_161616BE;
     auto src_alpha_format =
         has_alpha ? skcms_AlphaFormat_Unpremul : skcms_AlphaFormat_Opaque;
     auto dst_alpha_format = has_alpha ? (buffer.PremultiplyAlpha()
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index c76a217..49f94173 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1019,12 +1019,6 @@
       settable_from_internals: true,
       status: "experimental",
     },
-    // This feature refers to the API that delivers notifications to pages on
-    // lifecycle state changes.
-    {
-      name: "PageLifecycle",
-      status: "stable",
-    },
     // The following are developer opt-outs and opt-ins for PageLifecycle state
     // transitions. If neither is specified then heuristics will be applied to
     // determine whether the page is eligible.
diff --git a/third_party/blink/renderer/platform/testing/test_paint_artifact.cc b/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
index 989892c..ae2f359 100644
--- a/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
+++ b/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
@@ -108,6 +108,11 @@
   return *this;
 }
 
+TestPaintArtifact& TestPaintArtifact::OutsetForRasterEffects(float outset) {
+  paint_chunks_.back().outset_for_raster_effects = outset;
+  return *this;
+}
+
 TestPaintArtifact& TestPaintArtifact::KnownToBeOpaque() {
   paint_chunks_.back().known_to_be_opaque = true;
   return *this;
diff --git a/third_party/blink/renderer/platform/testing/test_paint_artifact.h b/third_party/blink/renderer/platform/testing/test_paint_artifact.h
index 342ea08..3e732a8 100644
--- a/third_party/blink/renderer/platform/testing/test_paint_artifact.h
+++ b/third_party/blink/renderer/platform/testing/test_paint_artifact.h
@@ -112,6 +112,7 @@
   // display items.
   TestPaintArtifact& Bounds(const IntRect&);
 
+  TestPaintArtifact& OutsetForRasterEffects(float);
   TestPaintArtifact& KnownToBeOpaque();
   TestPaintArtifact& Uncacheable();
 
diff --git a/third_party/blink/renderer/platform/text/character.cc b/third_party/blink/renderer/platform/text/character.cc
index 381135c..faba1e4f 100644
--- a/third_party/blink/renderer/platform/text/character.cc
+++ b/third_party/blink/renderer/platform/text/character.cc
@@ -43,8 +43,7 @@
 #if defined(USING_SYSTEM_ICU)
 #include <unicode/uniset.h>
 #else
-#define MUTEX_H  // Prevent compile failure of utrie2.h on Windows
-#include <utrie2.h>
+#include <unicode/ucptrie.h>
 #endif
 
 namespace blink {
@@ -73,21 +72,22 @@
     unicodeSet = CREATE_UNICODE_SET(name);      \
   return unicodeSet->contains(c);
 #else
-static UTrie2* CreateTrie() {
+static UCPTrie* CreateTrie() {
   // Create a Trie from the value array.
   ICUError error;
-  UTrie2* trie = utrie2_openFromSerialized(
-      UTrie2ValueBits::UTRIE2_16_VALUE_BITS, kSerializedCharacterData,
-      kSerializedCharacterDataSize, nullptr, &error);
+  UCPTrie* trie = ucptrie_openFromBinary(
+      UCPTrieType::UCPTRIE_TYPE_FAST, UCPTrieValueWidth::UCPTRIE_VALUE_BITS_16,
+      kSerializedCharacterData, kSerializedCharacterDataSize, nullptr, &error);
   DCHECK_EQ(error, U_ZERO_ERROR);
   return trie;
 }
 
 static bool HasProperty(UChar32 c, CharacterProperty property) {
-  static UTrie2* trie = nullptr;
+  static UCPTrie* trie = nullptr;
   if (!trie)
     trie = CreateTrie();
-  return UTRIE2_GET16(trie, c) & static_cast<CharacterPropertyType>(property);
+  return UCPTRIE_FAST_GET(trie, UCPTRIE_16, c) &
+         static_cast<CharacterPropertyType>(property);
 }
 
 #define RETURN_HAS_PROPERTY(c, name) \
diff --git a/third_party/blink/renderer/platform/text/character_property_data_generator.cc b/third_party/blink/renderer/platform/text/character_property_data_generator.cc
index 893d527..13cb44b0 100644
--- a/third_party/blink/renderer/platform/text/character_property_data_generator.cc
+++ b/third_party/blink/renderer/platform/text/character_property_data_generator.cc
@@ -4,14 +4,16 @@
 
 #include "third_party/blink/renderer/platform/text/character_property_data.h"
 
+#include "base/logging.h"
+
 #include <stdio.h>
 #include <cassert>
 #include <cstring>
 #include <memory>
 #include "third_party/blink/renderer/platform/text/character_property.h"
 #if !defined(USING_SYSTEM_ICU)
-#define MUTEX_H  // Prevent compile failure of utrie2.h on Windows
-#include <utrie2.h>
+#include <unicode/ucptrie.h>
+#include <unicode/umutablecptrie.h>
 #endif
 
 namespace blink {
@@ -87,7 +89,8 @@
 
   // Create a trie from the value array.
   UErrorCode error = U_ZERO_ERROR;
-  UTrie2* trie = utrie2_open(0, 0, &error);
+  std::unique_ptr<UMutableCPTrie, decltype(&umutablecptrie_close)> trie(
+      umutablecptrie_open(0, 0, &error), umutablecptrie_close);
   assert(error == U_ZERO_ERROR);
   UChar32 start = 0;
   CharacterProperty value = values[0];
@@ -95,8 +98,8 @@
     if (c < kSize && values[c] == value)
       continue;
     if (static_cast<uint32_t>(value)) {
-      utrie2_setRange32(trie, start, c - 1, static_cast<uint32_t>(value), TRUE,
-                        &error);
+      umutablecptrie_setRange(trie.get(), start, c - 1,
+                              static_cast<uint32_t>(value), &error);
       assert(error == U_ZERO_ERROR);
     }
     if (c >= kSize)
@@ -105,19 +108,28 @@
     value = values[start];
   }
 
-  // Freeze and serialize the trie to a byte array.
-  utrie2_freeze(trie, UTrie2ValueBits::UTRIE2_16_VALUE_BITS, &error);
+  // Convert to immutable UCPTrie in order to be able to serialize.
+  std::unique_ptr<UCPTrie, decltype(&ucptrie_close)> immutable_trie(
+      umutablecptrie_buildImmutable(trie.get(), UCPTrieType::UCPTRIE_TYPE_FAST,
+                                    UCPTrieValueWidth::UCPTRIE_VALUE_BITS_16,
+                                    &error),
+      ucptrie_close);
+
   assert(error == U_ZERO_ERROR);
-  int32_t serialized_size = utrie2_serialize(trie, nullptr, 0, &error);
+
+  int32_t serialized_size =
+      ucptrie_toBinary(immutable_trie.get(), nullptr, 0, &error);
   error = U_ZERO_ERROR;
+
   std::unique_ptr<uint8_t[]> serialized(new uint8_t[serialized_size]);
-  serialized_size =
-      utrie2_serialize(trie, serialized.get(), serialized_size, &error);
+  // Ensure 32-bit alignment, as ICU requires that to the ucptrie_toBinary call.
+  CHECK(!(reinterpret_cast<intptr_t>(serialized.get()) % 4));
+
+  serialized_size = ucptrie_toBinary(immutable_trie.get(), serialized.get(),
+                                     serialized_size, &error);
   assert(error == U_ZERO_ERROR);
 
   GenerateUTrieSerialized(fp, serialized_size, serialized.get());
-
-  utrie2_close(trie);
 }
 #endif
 
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
index 84df4e3..6ce9952 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -338,33 +338,32 @@
 crbug.com/916511 virtual/composite-after-paint/paint/background/scrolling-background-with-negative-z-child.html [ Crash ]
 crbug.com/591099 virtual/composite-after-paint/paint/invalidation/box/margin.html [ Failure Pass ]
 Bug(none) virtual/disable-blink-gen-property-trees/ [ Skip ]
-crbug.com/917392 virtual/display-lock/display-lock/lock-after-append/acquire-after-resize.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/lock-after-append/measure-forced-layout-after-commit.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/lock-after-append/measure-forced-layout.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/lock-after-append/measure-updated-layout.html [ Failure ]
-crbug.com/926276 virtual/display-lock/display-lock/lock-after-append/nested-update-and-commit.html [ Timeout ]
-crbug.com/926276 virtual/display-lock/display-lock/lock-after-append/nested-update.html [ Timeout ]
-crbug.com/917392 virtual/display-lock/display-lock/lock-before-append/acquire-update-measure-remove.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/lock-before-append/measure-forced-layout.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/lock-before-append/measure-updated-layout.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/acquire-size-used-when-auto-size-border.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/acquire-size-used-when-auto-size.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/flex-row-horizontal-with-grow.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/flex-row-horizontal.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/flex-row-vertical-with-grow.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/flex-row-vertical.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/layout-replaced.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/writing-modes.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/writing-modes-switch.html [ Failure ]
-crbug.com/955533 virtual/display-lock/display-lock/sizing/overflow-auto-with-overflow.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/min-width-respected.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/float-left.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/lock-after-append/acquire-after-resize.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/lock-after-append/measure-forced-layout-after-commit.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/lock-after-append/measure-forced-layout.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/lock-after-append/measure-updated-layout.html [ Failure ]
+crbug.com/926276 virtual/display-lock/wpt_internal/display-lock/lock-after-append/nested-update-and-commit.html [ Timeout ]
+crbug.com/926276 virtual/display-lock/wpt_internal/display-lock/lock-after-append/nested-update.html [ Timeout ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/lock-before-append/acquire-update-measure-remove.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/lock-before-append/measure-forced-layout.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/lock-before-append/measure-updated-layout.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/flex-row-horizontal-with-grow.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/flex-row-horizontal.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/flex-row-vertical-with-grow.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/flex-row-vertical.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/writing-modes.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/writing-modes-switch.html [ Failure ]
+crbug.com/955533 virtual/display-lock/wpt_internal/display-lock/sizing/overflow-auto-with-overflow.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/min-width-respected.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/float-left.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/writing-modes-inherited-after-append.html [ Failure ]
+crbug.com/917392 virtual/display-lock/wpt_internal/display-lock/sizing/max-content-size-ignored.html [ Failure ]
 crbug.com/591099 virtual/display-lock/http/tests/devtools/elements/highlight/highlight-display-locked.js [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/writing-modes-inherited-after-append.html [ Failure ]
-crbug.com/917392 virtual/display-lock/display-lock/sizing/max-content-size-ignored.html [ Failure ]
 crbug.com/591099 virtual/exotic-color-space/ [ Skip ]
 crbug.com/591099 virtual/fractional_scrolling_threaded/fast/scrolling/unscrollable-layer-subpixel-size-with-negative-overflow.html [ Failure Pass ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Pass ]
@@ -394,7 +393,4 @@
 crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects-continuation.html [ Failure ]
 crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Failure ]
 crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
-crbug.com/591099 virtual/video-surface-layer/media/W3C/video/networkState/networkState_during_progress.html [ Pass ]
-crbug.com/591099 virtual/video-surface-layer/media/color-profile-video-seek-filter.html [ Pass ]
-crbug.com/591099 virtual/video-surface-layer/media/stable/video-object-fit-stable.html [ Pass ]
 crbug.com/591099 vr/getFrameData_oneframeupdate.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations
index a1fb0f05..2e2c65a 100644
--- a/third_party/blink/web_tests/LeakExpectations
+++ b/third_party/blink/web_tests/LeakExpectations
@@ -78,7 +78,6 @@
 crbug.com/862029 [ Linux ] virtual/threaded/http/tests/devtools/tracing/timeline-misc/timeline-window-filter.js [ Pass Leak ]
 
 crbug.com/733494 [ Linux ] media/autoplay/document-user-activation.html [ Pass Leak ]
-crbug.com/733494 [ Linux ] virtual/video-surface-layer/media/autoplay/document-user-activation.html [ Pass Leak ]
 
 # Sheriff 2019-01-04
 crbug.com/919117 [ Linux ] virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-drag.html [ Pass Leak ]
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations
index 52dc881..79cce992 100644
--- a/third_party/blink/web_tests/MSANExpectations
+++ b/third_party/blink/web_tests/MSANExpectations
@@ -164,7 +164,6 @@
 crbug.com/856601 [ Linux ] virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/interfaces-sw.https.html [ Timeout Pass ]
 crbug.com/856601 [ Linux ] virtual/outofblink-cors/external/wpt/service-workers/service-worker/interfaces-sw.https.html [ Timeout Pass ]
 crbug.com/856601 [ Linux ] virtual/service-worker-servicification/external/wpt/service-workers/service-worker/interfaces-sw.https.html [ Timeout Pass ]
-crbug.com/856601 [ Linux ] virtual/video-surface-layer/external/wpt/picture-in-picture/idlharness.window.html [ Pass Failure Timeout ]
 crbug.com/856601 [ Linux ] external/wpt/fetch/api/idl.any.sharedworker.html [ Pass Timeout ]
 crbug.com/856601 [ Linux ] external/wpt/fetch/cors-rfc1918/idlharness.tentative.https.any.serviceworker.html [ Pass Timeout ]
 crbug.com/856601 [ Linux ] external/wpt/media-capabilities/idlharness.any.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index 1e6f032..f055b6d 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -1679,9 +1679,6 @@
 # direct compositing reason (for performance). Only applies to SPv1.
 paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html [ WontFix ]
 
-# This test will only work in the "video-surface-layer" virtual test suite.
-media/picture-in-picture/picture-in-picture-interstitial-sizing.html [ WontFix ]
-
 # Tests that use too much storage for automation.
 http/tests/cachestorage/large-put.html [ WontFix ]
 
@@ -1699,9 +1696,6 @@
 crbug.com/869492 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.html [ WontFix ]
 crbug.com/869492 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html [ WontFix ]
 crbug.com/869492 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/lazyload-image-attribute-on-sanity-check-tentative.sub.html [ WontFix ]
-crbug.com/869492 virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.html [ WontFix ]
-crbug.com/869492 virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html [ WontFix ]
-crbug.com/869492 virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/lazyload/lazyload-image-attribute-on-sanity-check-tentative.sub.html [ WontFix ]
 
 # Tests that are not supported if outofblink-cors feature is enabled.
 # These functionarities should be verified on browser_tests for outofblink-cors.
@@ -2299,7 +2293,6 @@
 crbug.com/946022 [ Win7 ] images/image-zoom-to-25.html [ WontFix ]
 crbug.com/946022 [ Win7 ] images/image-zoom-to-500.html [ WontFix ]
 crbug.com/946022 [ Win7 ] media/controls/overflow-menu-hide-on-resize.html [ WontFix ]
-crbug.com/946022 [ Win7 ] virtual/video-surface-layer/media/controls/overflow-menu-hide-on-resize.html [ WontFix ]
 crbug.com/946022 [ Win7 ] paint/invalidation/resize-iframe-text.html [ WontFix ]
 crbug.com/946022 [ Win7 ] paint/invalidation/scroll/scrollbar-damage-and-full-viewport-repaint.html [ WontFix ]
 crbug.com/946022 [ Win7 ] paint/invalidation/window-resize/ [ WontFix ]
@@ -2321,3 +2314,5 @@
 external/wpt/pointerevents/pointerevent_touch-action-inherit_child-none_touch-manual.html [ WontFix ]
 external/wpt/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html [ WontFix ]
 external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html [ WontFix ]
+external/wpt/web-share/share-files-manual.html [ WontFix ]
+external/wpt/web-share/share-image-manual.html [ WontFix ]
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests
index e35d677b..b2430d9 100644
--- a/third_party/blink/web_tests/SlowTests
+++ b/third_party/blink/web_tests/SlowTests
@@ -46,9 +46,7 @@
 crbug.com/24182 jquery/offset.html [ Slow ]
 crbug.com/24182 jquery/traversing.html [ Slow ]
 crbug.com/24182 media/controls/controls-cast-do-not-fade-out.html [ Slow ]
-crbug.com/24182 virtual/video-surface-layer/media/controls/controls-cast-do-not-fade-out.html [ Slow ]
 crbug.com/24182 media/controls/controls-cast-overlay-slow-fade.html [ Slow ]
-crbug.com/24182 virtual/video-surface-layer/media/controls/controls-cast-overlay-slow-fade.html [ Slow ]
 crbug.com/24182 svg/filters/big-sized-filter.svg [ Slow ]
 crbug.com/24182 tables/mozilla/other/slashlogo.html [ Slow ]
 crbug.com/24182 fast/canvas/color-space/canvas-colorManaged-toBlob-toDataURL.html [ Slow ]
@@ -237,7 +235,6 @@
 crbug.com/451577 [ Linux ] http/tests/devtools/layers/layer-canvas-log.js [ Slow ]
 
 crbug.com/793771 media/controls/modern/scrubbing.html [ Slow ]
-crbug.com/793771 virtual/video-surface-layer/media/controls/modern/scrubbing.html [ Slow ]
 
 # These tests need to do many iterations and so can't be fast.
 crbug.com/748418 http/tests/streams/chromium/deep-recursion-getwriter.html [ Slow ]
@@ -280,10 +277,8 @@
 crbug.com/864887 [ Mac ] fast/scroll-snap/snaps-after-scrollbar-scrolling.html [ Slow ]
 
 crbug.com/865262 [ Mac ] media/controls/text-track-menu-pointer-selection.html [ Slow ]
-crbug.com/876050 [ Mac ] virtual/video-surface-layer/media/controls/text-track-menu-pointer-selection.html [ Slow ]
 
 crbug.com/942951 media/controls/controls-layout-in-different-size.html [ Slow ]
-crbug.com/942951 virtual/video-surface-layer/media/controls/controls-layout-in-different-size.html [ Slow ]
 
 crbug.com/910627 webexposed/global-interface-listing-shared-worker.html [ Slow ]
 crbug.com/910627 virtual/stable/webexposed/global-interface-listing-shared-worker.html [ Slow ]
@@ -819,37 +814,6 @@
 crbug.com/874695 virtual/user-activation-v2/fullscreen/full-screen-restrictions.html [ Slow ]
 crbug.com/874695 virtual/user-activation-v2/fullscreen/model/fully-exit-fullscreen-nested-iframe.html [ Slow ]
 crbug.com/874695 virtual/user-activation-v2/fullscreen/rendering/overflow.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/audio-controls-do-not-fade-out.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/autoplay-muted.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/autoplay-when-visible.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/color-profile-video-seek-filter.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/controls/offline-play-button.mht [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/controls-strict.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/controls/video-overlay-cast-dark-rendering.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/encrypted-media/encrypted-media-onencrypted.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/encrypted-media/encrypted-media-setmediakeys-at-same-time.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/media-controls-grey-scrubber.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/media-controls-tap-show-controls-without-activating.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/media-document-audio-repaint.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/media-ended.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/stable/video-object-fit-stable.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/track/track-cue-gc-wrapper.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/track/track-cue-rendering-position-auto.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-always-visible-when-control-hovered.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-auto-hide-after-play-by-touch.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-dont-show-on-focus-when-disabled.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-focus-movement-on-hide.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-hide-after-touch-on-control.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-hide-on-move-outside-controls.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-show-on-focus.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-visibility-multimodal-mouse-after-touch.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-controls-visibility-multimodal-touch-after-mouse.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-object-fit-change.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-played-collapse.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-poster-after-playing.html [ Slow ]
-crbug.com/874695 virtual/video-surface-layer/media/video-poster-load-after-playing.html [ Slow ]
 
 crbug.com/868956 virtual/gpu/fast/canvas/canvas-composite-video-shadow.html [ Slow ]
 
@@ -876,7 +840,6 @@
 crbug.com/912364 [ Mac ] virtual/user-activation-v2/fast/events/no-fake-mousemove.html [ Slow ]
 crbug.com/914981 [ Mac ] media/controls/overflow-menu-pointer-selection.html [ Slow ]
 crbug.com/914981 [ Mac ] virtual/mouseevent_fractional/fast/events/no-fake-mousemove.html [ Slow ]
-crbug.com/914981 [ Mac ] virtual/video-surface-layer/media/controls/overflow-menu-pointer-selection.html [ Slow ]
 crbug.com/914981 [ Mac ] fast/events/no-fake-mousemove.html [ Slow ]
 
 crbug.com/951895 [ Mac Debug ] transforms/2d/transform-2d.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index c5e380e..ab88250 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -261,11 +261,11 @@
 crbug.com/414283 virtual/fractional_scrolling_threaded/fast/scrolling/fractional-scroll-offset-iframe-fixed-position.html [ Failure Pass ]
 
 # Display locking, currently only available via a virtual test.
-crbug.com/882663 display-lock [ Skip ]
-crbug.com/926276 virtual/display-lock/display-lock/lock-after-append/nested-update.html [ Timeout ]
-crbug.com/926276 virtual/display-lock/display-lock/lock-after-append/nested-update-and-commit.html [ Timeout ]
-crbug.com/933544 virtual/display-lock/display-lock/lock-after-append/acquire-on-composited-layer.html [ Crash Pass ]
-crbug.com/955533 virtual/display-lock/display-lock/sizing/overflow-auto-with-overflow.html [ Failure ]
+crbug.com/882663 wpt_internal/display-lock [ Skip ]
+crbug.com/926276 virtual/display-lock/wpt_internal/display-lock/lock-after-append/nested-update.html [ Timeout ]
+crbug.com/926276 virtual/display-lock/wpt_internal/display-lock/lock-after-append/nested-update-and-commit.html [ Timeout ]
+crbug.com/933544 virtual/display-lock/wpt_internal/display-lock/lock-after-append/acquire-on-composited-layer.html [ Crash Pass ]
+crbug.com/955533 virtual/display-lock/wpt_internal/display-lock/sizing/overflow-auto-with-overflow.html [ Failure ]
 crbug.com/882663 http/tests/devtools/elements/highlight/highlight-display-locked.js [ Skip ]
 
 # Sheriff 2018/05/25
@@ -306,8 +306,7 @@
 crbug.com/887000 virtual/prefer_compositing_to_lcd_text/scrollbars/hidden-scrollbars-invisible.html [ Failure ]
 crbug.com/882975 virtual/threaded/fast/events/pinch/gesture-pinch-zoom-prevent-in-handler.html [ Failure Pass ]
 crbug.com/882975 virtual/threaded/fast/events/pinch/scroll-visual-viewport-send-boundary-events.html [ Failure Pass ]
-crbug.com/884239 virtual/threaded/animations/animationworklet/worklet-animation-local-time-undefined.html [ Timeout Failure Pass ]
-crbug.com/884239 virtual/disable-blink-gen-property-trees/animations/animationworklet/worklet-animation-local-time-undefined.html [ Skip ]
+
 # Subpixel rounding differences that are incorrect.
 crbug.com/836886 virtual/prefer_compositing_to_lcd_text/compositing/overflow/scaled-overflow.html [ Failure ]
 crbug.com/836886 compositing/overflow/scaled-overflow.html [ Failure ]
@@ -507,8 +506,6 @@
 crbug.com/949909 external/wpt/css/css-text-decor/text-decoration-040-manual.html [ Skip ]
 
 crbug.com/722825 media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout Pass ]
-crbug.com/722825 virtual/video-surface-layer/media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout Pass ]
-crbug.com/876050 virtual/video-surface-layer/media/controls/text-track-menu-pointer-selection.html [ Pass Failure ]
 
 #### crbug.com/783229 overflow
 crbug.com/724701 overflow/overflow-basic-004.html [ Failure ]
@@ -1902,13 +1899,6 @@
 crbug.com/520736 [ Win7 ] media/W3C/video/networkState/networkState_during_progress.html [ Failure Pass ]
 crbug.com/520736 [ Linux ] media/W3C/video/networkState/networkState_during_progress.html [ Failure Pass ]
 crbug.com/909095 [ Mac ] media/W3C/video/networkState/networkState_during_progress.html [ Failure Pass ]
-# This is also flaky from findit, see crbug.com/903019:
-crbug.com/520736 virtual/video-surface-layer/media/W3C/video/networkState/networkState_during_progress.html [ Pass Failure Timeout Crash ]
-
-crbug.com/841922 [ Linux ] virtual/video-surface-layer/media/video-controls-focus-movement-on-hide.html [ Pass Failure ]
-crbug.com/841922 [ Win ] virtual/video-surface-layer/media/video-controls-focus-movement-on-hide.html [ Pass Failure ]
-crbug.com/841922 [ Mac ] virtual/video-surface-layer/media/video-controls-focus-movement-on-hide.html [ Pass Failure ]
-
 
 crbug.com/862716 [ Mac ] css3/filters/effect-brightness-clamping-hw.html [ Failure Pass Timeout ]
 crbug.com/862716 [ Linux ] css3/filters/effect-brightness-clamping-hw.html [ Failure Pass Timeout ]
@@ -2323,7 +2313,6 @@
 crbug.com/467635 fast/dom/HTMLImageElement/image-sizes-meta-viewport.html [ Skip ]
 
 crbug.com/636239 [ Win7 ] media/video-zoom-controls.html [ Failure ]
-crbug.com/636239 [ Win7 ] virtual/video-surface-layer/media/video-zoom-controls.html [ Failure ]
 
 # Printing Layout broken in these tests.
 crbug.com/377696 printing/setPrinting.html [ Skip ]
@@ -2375,7 +2364,6 @@
 crbug.com/674225 [ Mac ] fast/replaced/input-radio-height-inside-auto-container.html [ Failure ]
 
 crbug.com/400841 media/video-canvas-draw.html [ Failure ]
-crbug.com/400841 virtual/video-surface-layer/media/video-canvas-draw.html [ Failure ]
 crbug.com/400829 virtual/stable/media/stable/video-object-fit-stable.html [ Failure ]
 
 # These contain faulty expectations. https://chromium-review.googlesource.com/c/v8/v8/+/1350790 should fix the
@@ -2441,7 +2429,6 @@
 
 # These tests are skipped as there is no touch support on Mac.
 crbug.com/613672 [ Mac ] external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ]
-crbug.com/613672 [ Mac ] virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ]
 crbug.com/613672 [ Mac ] virtual/unified-autoplay/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ]
 crbug.com/613672 [ Mac ] fast/events/pointerevents/multi-pointer-event-in-slop-region.html [ Skip ]
 crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/multi-pointer-event-in-slop-region.html [ Skip ]
@@ -2450,7 +2437,7 @@
 crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ]
 crbug.com/613672 [ Mac ] virtual/user-activation-v2/fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ]
 # In addition to having no support on Mac, the following test times out
-# regularly on Windows. crbug.com/850964
+# regularly on Windows.
 crbug.com/613672 [ Mac ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ]
 crbug.com/613672 [ Win ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ]
 crbug.com/613672 [ Mac ] fast/events/touch/gesture/gesture-scroll.html [ Skip ]
@@ -2769,7 +2756,6 @@
 crbug.com/654477 fast/layers/video-layer.html [ Failure ]
 # These could likely be removed - see https://chromium-review.googlesource.com/c/chromium/src/+/1252141
 crbug.com/654477 media/controls-focus-ring.html [ Failure ]
-crbug.com/654477 virtual/video-surface-layer/media/controls-focus-ring.html [ Failure ]
 crbug.com/654477 [ Mac10.10 ] http/tests/media/video-buffered-range-contains-currentTime.html [ Failure ]
 crbug.com/654477 [ Mac10.11 ] http/tests/media/video-buffered-range-contains-currentTime.html [ Failure ]
 crbug.com/654477 [ Retina ] http/tests/media/video-buffered-range-contains-currentTime.html [ Failure ]
@@ -3037,6 +3023,9 @@
 crbug.com/939181 virtual/not-site-per-process/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Failure Timeout ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac10.10 ] external/wpt/animation-worklet/worklet-animation-with-scroll-timeline.https.html [ Failure ]
+crbug.com/626703 [ Mac10.10 ] external/wpt/animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html [ Failure ]
+crbug.com/626703 [ Mac10.11 ] external/wpt/animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-text/hyphens/hyphens-shaping-002.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-text/hyphens/hyphens-shaping-001.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-002.html [ Failure ]
@@ -4750,7 +4739,6 @@
 crbug.com/722212 virtual/user-activation-v2/fast/events/pointerevents/mouse-pointer-event-properties.html [ Failure Timeout Pass ]
 # Crashes on win
 crbug.com/722943 media/audio-repaint.html [ Skip ]
-crbug.com/722943 virtual/video-surface-layer/media/audio-repaint.html [ Skip ]
 
 # Sheriff failures 2018-08-13
 crbug.com/873454 css3/filters/effect-reference-image-hw.html [ Failure Pass ]
@@ -4778,7 +4766,6 @@
 crbug.com/718155 fullscreen/full-screen-iframe-not-allowed.html [ Failure ]
 crbug.com/718155 fullscreen/full-screen-restrictions.html [ Failure Timeout ]
 crbug.com/718155 media/video-controls-fullscreen-iframe-not-allowed.html [ Failure ]
-crbug.com/718155 virtual/video-surface-layer/media/video-controls-fullscreen-iframe-not-allowed.html [ Failure ]
 crbug.com/718155 virtual/android/fullscreen/full-screen-iframe-not-allowed.html [ Failure ]
 crbug.com/718155 virtual/android/fullscreen/full-screen-restrictions.html [ Failure Timeout ]
 crbug.com/718155 virtual/user-activation-v2/fullscreen/full-screen-iframe-not-allowed.html [ Failure ]
@@ -4852,11 +4839,8 @@
 crbug.com/831957 compositing/video/video-controls-layer-creation-squashing.html [ Failure Pass ]
 crbug.com/832157 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-after-controls-added.html [ Skip ]
 crbug.com/832169 media/media-controls-fit-properly-while-zoomed.html [ Failure Pass ]
-crbug.com/832169 virtual/video-surface-layer/media/media-controls-fit-properly-while-zoomed.html [ Failure Pass ]
 crbug.com/832447 media/controls/controls-page-zoom-in.html [ Failure Pass ]
 crbug.com/832447 media/controls/controls-page-zoom-out.html [ Failure Pass ]
-crbug.com/832447 virtual/video-surface-layer/media/controls/controls-page-zoom-in.html [ Failure Pass ]
-crbug.com/832447 virtual/video-surface-layer/media/controls/controls-page-zoom-out.html [ Failure Pass ]
 crbug.com/849694 [ Mac ] http/tests/media/controls/toggle-class-with-state-source-buffer.html [ Failure Pass ]
 
 # ContentSecurityPolicy modifies the SchemeRegistry before some initialization.
@@ -4979,8 +4963,6 @@
 crbug.com/694855 media/audio-src-suspend-after-have-metadata.html [ Skip ]
 crbug.com/694855 media/video-src-skip-suspend-after-have-metadata.html [ Skip ]
 crbug.com/694855 media/video-src-suspend-after-have-metadata.html [ Skip ]
-crbug.com/694855 virtual/video-surface-layer/media/audio-src-suspend-after-have-metadata.html [ Skip ]
-crbug.com/694855 virtual/video-surface-layer/media/video-src-suspend-after-have-metadata.html [ Skip ]
 
 ### See crbug.com/891427 comment near the top of this file:
 ###crbug.com/849979 media/video-layer-crash.html [ Pass Timeout ]
@@ -5102,22 +5084,13 @@
 crbug.com/783154 [ Mac ] media/controls/modern/doubletap-on-play-button.html [ Skip ]
 crbug.com/783154 [ Mac ] media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ]
 crbug.com/783154 [ Mac ] media/controls/click-anywhere-to-play-pause.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-backwards.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-forwards.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-on-play-button.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/click-anywhere-to-play-pause.html [ Skip ]
 
 # Seen flaky on Linux, suppressing on Windows as well
 crbug.com/831720 [ Win ] media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
 crbug.com/831720 [ Linux ] media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
-crbug.com/831720 [ Win ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
-crbug.com/831720 [ Linux ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
 crbug.com/831720 [ Mac ] media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 crbug.com/831720 [ Win ] media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 crbug.com/831720 [ Linux ] media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
-crbug.com/831720 virtual/video-surface-layer/media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 
 crbug.com/802915 css3/blending/isolation-should-include-non-local-background.html [ Failure ]
 
@@ -5128,7 +5101,6 @@
 
 # Does not work on Mac
 crbug.com/793771 [ Mac ] media/controls/modern/scrubbing.html [ Skip ]
-crbug.com/914981 [ Mac ] virtual/video-surface-layer/media/controls/modern/scrubbing.html [ Skip ]
 crbug.com/916902 [ Mac ] virtual/fractional_scrolling/fast/scrolling/overflow-scrollability.html [ Skip ]
 
 # Different paths may have different anti-aliasing pixels 2018-02-21
@@ -5159,7 +5131,6 @@
 crbug.com/814585 [ Linux ] fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-cjk.html [ Pass Failure ]
 
 # Sheriff failures 2018-02-22
-crbug.com/789921 virtual/video-surface-layer/media/controls/repaint-on-resize.html [ Failure Pass ]
 crbug.com/814889 idle-callback/test-runner-run-idle-tasks.html [ Crash Timeout Pass ]
 crbug.com/814953 fast/replaced/no-focus-ring-iframe.html [ Failure Pass ]
 crbug.com/814964 virtual/gpu-rasterization/images/color-profile-border-radius.html [ Failure Pass ]
@@ -5181,22 +5152,7 @@
 crbug.com/807110 external/wpt/media-source/mediasource-sequencemode-append-buffer.html [ Failure Pass ]
 crbug.com/807110 external/wpt/media-source/mediasource-sourcebuffer-mode-timestamps.html [ Failure Pass ]
 crbug.com/794338 media/video-rotation.html [ Failure Pass ]
-crbug.com/794338 virtual/video-surface-layer/media/video-rotation.html [ Failure Pass ]
 crbug.com/811605 media/video-poster-after-loadedmetadata.html [ Failure Pass ]
-crbug.com/811605 virtual/video-surface-layer/media/video-poster-after-loadedmetadata.html [ Failure Pass ]
-crbug.com/860368 virtual/video-surface-layer/media/autoplay/webaudio-audio-context-resume.html  [ Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/controls/captions-menu-always-visible.html [ Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg.html [ Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none.html [ Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/track/track-cue-rendering-position-auto-rtl.html [ Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/video-frame-accurate-seek.html [ Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/video-zoom.html [ Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/controls/volumechange-muted-attribute.html [ Timeout Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/video-persistence.html [ Timeout Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/color-profile-video.html [ Timeout Pass Failure ]
-crbug.com/860368 virtual/video-surface-layer/media/controls/modern/singletouch-on-play-button.html [ Timeout Pass ]
-crbug.com/860368 virtual/video-surface-layer/media/controls/lazy-loaded-style.html [ Pass Failure ]
 
 crbug.com/813704 http/tests/images/png-partial-load-as-document.html [ Failure Pass ]
 
@@ -5232,8 +5188,6 @@
 # Sheriff 2018-03-22
 crbug.com/824775 [ Win ] media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
 crbug.com/824775 [ Mac ] media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
-crbug.com/824775 [ Win ] virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
-crbug.com/824775 [ Mac ] virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
 crbug.com/824830 fast/peerconnection/RTCPeerConnection-many.html [ Timeout Crash Failure Pass ]
 crbug.com/824848 [ Linux ] external/wpt/html/semantics/links/following-hyperlinks/activation-behavior.window.html [ Pass Failure ]
 crbug.com/824848 [ Mac ] external/wpt/html/semantics/links/following-hyperlinks/activation-behavior.window.html [ Pass Failure ]
@@ -5255,9 +5209,7 @@
 
 # Sheriff 2018-03-26
 crbug.com/825733 [ Win ] media/color-profile-video-seek-filter.html [ Pass Timeout Failure ]
-crbug.com/825733 virtual/video-surface-layer/media/color-profile-video-seek-filter.html [ Pass Timeout Failure ]
 crbug.com/754986 media/video-transformed.html [ Pass Failure ]
-crbug.com/754986 virtual/video-surface-layer/media/video-transformed.html [ Pass Failure ]
 
 # Sheriff 2018-03-29
 crbug.com/827088 bluetooth/requestDevice/chooser/new-scan-device-added.html [ Pass Crash ]
@@ -5308,7 +5260,6 @@
 
 # Sheriff 2018-04-13
 crbug.com/833655 [ Linux ] media/controls/closed-captions-dynamic-update.html [ Skip ]
-crbug.com/833655 [ Linux ] virtual/video-surface-layer/media/controls/closed-captions-dynamic-update.html [ Skip ]
 crbug.com/833658 [ Linux ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ]
 crbug.com/833658 [ Win ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ]
 crbug.com/833658 [ Mac ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ]
@@ -5320,10 +5271,6 @@
 # Sheriff 2018-04-25
 crbug.com/836783 fast/peerconnection/RTCRtpSender-setParameters.html [ Pass Timeout ]
 
-crbug.com/838254 virtual/video-surface-layer/media/webkit-media-controls-webkit-appearance.html [ Failure ]
-
-crbug.com/839332 [ Mac ] virtual/video-surface-layer/media/video-no-audio.html [ Pass Failure ]
-
 # Sheriff 2018-05-22
 crbug.com/845610 [ Win ] http/tests/inspector-protocol/target/target-browser-context.js [ Pass Failure ]
 
@@ -5359,7 +5306,6 @@
 
 # Flakes 2018-06-04
 crbug.com/847870 fast/webgl/texImage-imageBitmap-from-canvas-resize.html [ Timeout Pass ]
-crbug.com/847697 virtual/video-surface-layer/media/controls/overflow-menu-always-visible.html [ Pass Failure ]
 
 # Sheriff 2018-06-06
 crbug.com/849975 external/wpt/css/css-animations/Element-getAnimations.tentative.html [ Pass Failure ]
@@ -5411,7 +5357,6 @@
 # Sheriff 2018-06-18
 crbug.com/853852 [ Win7 ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-wheel-block-manual.tentative.html [ Pass Timeout ]
 crbug.com/853852 [ Linux ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-wheel-block-manual.tentative.html [ Pass Timeout ]
-crbug.com/853852 [ Linux ] virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html [ Skip ]
 
 crbug.com/854538 [ Win7 ] http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-with-redirect.html [ Skip ]
 crbug.com/854538 [ Win7 ] virtual/outofblink-cors/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-with-redirect.html [ Skip ]
@@ -5430,10 +5375,6 @@
 # User Activation
 crbug.com/736415 external/wpt/html/user-activation/activation-api-iframe.tenative.html [ Failure ]
 
-# wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html is flaky in some virtual/ tests.
-crbug.com/850964 [ Linux ] virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Pass Failure ]
-crbug.com/850964 [ Win ] virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Pass Failure ]
-
 # Sheriff 2018-07-05
 crbug.com/860731 fast/scroll-snap/animate-fling-to-snap-points.html [ Failure Pass ]
 crbug.com/861682 [ Win ] external/wpt/css/mediaqueries/device-aspect-ratio-003.html [ Failure Pass ]
@@ -5713,10 +5654,8 @@
 crbug.com/869492 virtual/unified-autoplay/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html [ Failure ]
 crbug.com/869492 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html [ Failure ]
 crbug.com/869492 virtual/unified-autoplay/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html [ Failure ]
-crbug.com/869492 virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html [ Failure ]
 crbug.com/869492 external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html [ Failure ]
 crbug.com/869492 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html [ Failure ]
-crbug.com/869492 virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html [ Failure ]
 crbug.com/869492 external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html [ Failure ]
 crbug.com/869492 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html [ Failure ]
 crbug.com/869492 virtual/unified-autoplay/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html [ Failure ]
@@ -5726,7 +5665,6 @@
 
 # Sheriff 2018-09-18
 crbug.com/884445 virtual/unified-autoplay/external/wpt/feature-policy/feature-policy-nested-header-policy-disallowed-for-all.https.sub.html [ Pass Timeout ]
-crbug.com/884445 virtual/video-surface-layer/external/wpt/feature-policy/feature-policy-nested-header-policy-disallowed-for-all.https.sub.html [ Pass Timeout ]
 
 # Sheriff 2018-09-19
 crbug.com/662010 [ Win7 ] http/tests/csspaint/invalidation-background-image.html [ Skip ]
@@ -5863,7 +5801,6 @@
 
 # Sheriff 2018-12-13
 crbug.com/910452 media/controls/buttons-after-reset.html [ Pass Failure ]
-crbug.com/910452 virtual/video-surface-layer/media/controls/buttons-after-reset.html [ Pass Failure ]
 crbug.com/914782 [ Linux ] fast/scrolling/no-hover-during-scroll.html [ Pass Failure ]
 
 # Sheriff 2018-12-14
@@ -6003,10 +5940,6 @@
 crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-misc/timeline-record-reload.js [ Skip ]
 crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-paint/timeline-paint-image.js [ Skip ]
 crbug.com/922951 virtual/user-activation-v2/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ]
-crbug.com/922951 virtual/video-surface-layer/media/controls/overflow-menu-hide-on-click-outside-stoppropagation.html [ Skip ]
-crbug.com/922951 virtual/video-surface-layer/media/controls/overflow-menu-hide-on-click-outside.html [ Skip ]
-crbug.com/922951 virtual/video-surface-layer/media/controls/overflow-menu-hide-on-click-panel.html [ Skip ]
-crbug.com/922951 virtual/video-surface-layer/media/controls/overflow-menu-toggle-class-for-animation.html [ Skip ]
 
 # Race: The RTCIceConnectionState can become "connected" before getStats()
 # returns candidate-pair whose state is "succeeded", this sounds like a
@@ -6078,9 +6011,6 @@
 crbug.com/849284 [ Win ] http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Failure Timeout ]
 crbug.com/849284 [ Win ] virtual/outofblink-cors/http/tests/fetch/serviceworker-proxied/thorough/redirect.html [ Timeout ]
 
-# Sheriff 2019-02-21
-crbug.com/934278 [ Mac ] virtual/video-surface-layer/media/video-object-fit.html [ Failure Pass ]
-
 # Sheriff 2019-02-22
 crbug.com/934636 http/tests/security/cross-origin-indexeddb-allowed.html [ Crash Pass ]
 crbug.com/934636 virtual/outofblink-cors/http/tests/security/cross-origin-indexeddb-allowed.html [ Crash Pass ]
@@ -6089,7 +6019,6 @@
 crbug.com/934818 virtual/threaded/http/tests/devtools/tracing/decode-resize.js [ Failure Pass ]
 
 # Sheriff 2019-02-25
-crbug.com/935587 [ Mac ] virtual/video-surface-layer/media/stable/video-object-fit-stable.html [ Failure Pass ]
 crbug.com/935689 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/symbols-function-invalid.html [ Failure Pass ]
 crbug.com/935689 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/system-additive-invalid.html [ Failure Pass ]
 crbug.com/935689 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/system-fixed-invalid.html [ Failure Pass ]
@@ -6100,7 +6029,6 @@
 crbug.com/936083 external/wpt/import-maps/builtin-import-scheme.tentative.html [ Failure Pass ]
 crbug.com/936095 fast/css-intrinsic-dimensions/height-tables-collapsed.html [ Failure Pass ]
 crbug.com/936165 media/autoplay-muted.html [ Timeout Pass ]
-crbug.com/936165 virtual/video-surface-layer/media/autoplay-muted.html [ Timeout Pass ]
 crbug.com/936108 virtual/streams-native/http/tests/streams/transferable/readable-stream.html [ Failure Pass ]
 
 # Sheriff 2019-02-27
@@ -6157,7 +6085,6 @@
 
 # Caused a revert of a good change.
 crbug.com/931533 media/video-played-collapse.html [ Pass Failure ]
-crbug.com/931533 virtual/video-surface-layer/media/video-played-collapse.html [ Pass Failure ]
 
 # Test was blocking WPT importer
 crbug.com/941471 external/wpt/css/css-transforms/transform-flattening-001.html [ Pass Failure Crash ]
@@ -6218,7 +6145,6 @@
 crbug.com/919789 images/image-zoom-to-25.html [ Pass Timeout ]
 crbug.com/919789 images/image-zoom-to-500.html [ Pass Timeout ]
 crbug.com/919789 media/controls/overflow-menu-hide-on-resize.html [ Pass Timeout ]
-crbug.com/919789 virtual/video-surface-layer/media/controls/overflow-menu-hide-on-resize.html [ Pass Timeout ]
 crbug.com/919789 paint/invalidation/resize-iframe-text.html [ Pass Timeout ]
 crbug.com/919789 paint/invalidation/scroll/scrollbar-damage-and-full-viewport-repaint.html [ Pass Timeout ]
 crbug.com/919789 paint/invalidation/window-resize/ [ Pass Timeout ]
@@ -6239,7 +6165,6 @@
 crbug.com/946712 [ Release ] http/tests/devtools/elements/styles-2/paste-property.js [ Crash Pass Timeout ]
 crbug.com/946713 [ Release ] http/tests/devtools/extensions/extensions-resources.js [ Crash Pass Timeout ]
 crbug.com/848799 [ Win7 ] http/tests/devtools/coverage/multiple-instances-merge.js [ Pass Timeout ]
-crbug.com/947126 [ Mac10.13 ] virtual/video-surface-layer/media/video-played-ranges-1.html [ Pass Failure ]
 crbug.com/942411 [ Win7 Linux ] http/tests/devtools/network/network-search.js [ Pass Timeout ]
 crbug.com/947383 inspector-protocol/css/reattach-after-editing-styles.js [ Pass Timeout ]
 
@@ -6282,7 +6207,6 @@
 crbug.com/951638 [ Win7 ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ]
 
 # Sheriff 2019-04-11
-crbug.com/951774 [ Linux ] virtual/video-surface-layer/media/controls/modern/overlay-play-button-tap-to-hide.html [ Pass Timeout ]
 crbug.com/951811 [ Mac10.13 ] external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-top-left.html [ Pass Timeout ]
 crbug.com/802029 [ Mac10.13 Debug ] fast/dom/shadow/focus-controller-recursion-crash.html [ Pass Timeout ]
 
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index a9facb10..3a34f5e 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -713,12 +713,6 @@
     "args": ["--disable-features=RTCUnifiedPlanByDefault"]
   },
   {
-    "prefix": "video-surface-layer",
-    "base": "media",
-    "args": ["--enable-features=UseSurfaceLayerForVideo",
-             "--enable-display-compositor-pixel-dump"]
-  },
-  {
     "prefix": "user-activation-v2",
     "base": "fast/dom/Window",
     "args": ["--enable-features=UserActivationV2"]
@@ -766,7 +760,7 @@
   },
   {
     "prefix": "display-lock",
-    "base": "display-lock",
+    "base": "wpt_internal/display-lock",
     "args": ["--enable-blink-features=DisplayLocking"]
   },
   {
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations
index eab9a49..e97c3fa 100644
--- a/third_party/blink/web_tests/WebDriverExpectations
+++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -127,7 +127,6 @@
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_contextmenu.py>>test_control_click[\ue009-ctrlKey] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new.py>>test_type_with_null_value [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_contextmenu.py>>test_release_control_click [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_resolve_delayed [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-alert] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress[2] [ Failure ]
diff --git a/third_party/blink/web_tests/accessibility/no-crash-modifying-dom-in-notification-callback-expected.txt b/third_party/blink/web_tests/accessibility/no-crash-modifying-dom-in-notification-callback-expected.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/third_party/blink/web_tests/accessibility/no-crash-modifying-dom-in-notification-callback-expected.txt
@@ -0,0 +1 @@
+
diff --git a/third_party/blink/web_tests/accessibility/no-crash-modifying-dom-in-notification-callback.html b/third_party/blink/web_tests/accessibility/no-crash-modifying-dom-in-notification-callback.html
new file mode 100644
index 0000000..ee263607
--- /dev/null
+++ b/third_party/blink/web_tests/accessibility/no-crash-modifying-dom-in-notification-callback.html
@@ -0,0 +1,27 @@
+<html>
+<head>
+<script>
+
+if (window.testRunner) {
+
+testRunner.waitUntilDone();
+testRunner.dumpAsText();
+
+accessibilityController.addNotificationListener(() => {
+  try {
+    document.open();
+    document.write();
+    gc();
+  } catch(e) {
+  }
+
+  testRunner.notifyDone();
+});
+
+var docElement = document.body ? document.body : document.documentElement;
+tCF3 = document.createElementNS("http://www.w3.org/1999/xhtml", "frame");
+docElement.appendChild(tCF3);
+
+}
+
+</script>
diff --git a/third_party/blink/web_tests/display-lock/activation/scroll-into-view-expected.html b/third_party/blink/web_tests/display-lock/activation/scroll-into-view-expected.html
deleted file mode 100644
index c07dd441..0000000
--- a/third_party/blink/web_tests/display-lock/activation/scroll-into-view-expected.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype HTML>
-
-<style>
-.spacer {
-  width: 150px;
-  height: 3000px;
-  background: lightblue;
-}
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightgreen;
-}
-#target {
-  width: 100px;
-  height: 100px;
-  background: green;
-}
-</style>
-
-<div class="spacer"></div>
-<div id="container"><div id="target"></div></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function notifyDone() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  document.getElementById("target").scrollIntoView();
-  requestAnimationFrame(notifyDone);
-}
-
-window.onload = () => { requestAnimationFrame(runTest); };
-</script>
diff --git a/third_party/blink/web_tests/display-lock/activation/scroll-into-view.html b/third_party/blink/web_tests/display-lock/activation/scroll-into-view.html
deleted file mode 100644
index 3a9baea..0000000
--- a/third_party/blink/web_tests/display-lock/activation/scroll-into-view.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!doctype HTML>
-
-<style>
-.spacer {
-  width: 150px;
-  height: 3000px;
-  background: lightblue;
-}
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightgreen;
-}
-#target {
-  width: 100px;
-  height: 100px;
-  background: green;
-}
-</style>
-
-<div class="spacer"></div>
-<div id="container"><div id="target"></div></div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, activatable: true }).then(() => {
-    document.getElementById("target").scrollIntoView();
-    requestAnimationFrame(finishTest);
-  });
-}
-
-window.onload = () => { requestAnimationFrame(runTest); };
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-after-resize-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-after-resize-expected.html
deleted file mode 100644
index d325504..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-after-resize-expected.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-}
-#spacer {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"></div>
-<div id="spacer"></div>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-after-resize.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-after-resize.html
deleted file mode 100644
index ce2f271..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-after-resize.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!doctype HTML>
-
-<!--
-Resizes the element and runs acquire, which should use the new size.
--->
-
-<style>
-.contained {
-  contain: style layout;
-  background: lightblue;
-}
-#spacer {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-<div id="small" class="contained"></div>
-<div id="spacer">
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("small");
-  container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-changed-containment-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-changed-containment-expected.html
deleted file mode 100644
index e2812ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-changed-containment-expected.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log">PASS Containment requirement is not satisfied.</div>
-<div id="container"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-changed-containment.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-changed-containment.html
deleted file mode 100644
index e82eef13..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-changed-containment.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
-Runs an acquire on an element with no containment after recalc, which fails.
--->
-
-<style>
-#container {
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log"></div>
-<div id="container" style="contain: style layout;"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.style = "";
-  container.displayLock.acquire({ timeout: Infinity }).then(
-    () => { finishTest("FAIL"); },
-    (e) => { finishTest("PASS " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-commit-resolves-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-commit-resolves-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-commit-resolves-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-commit-resolves.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-commit-resolves.html
deleted file mode 100644
index a284c0a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-commit-resolves.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire, and calls commit without waiting for the acquire promise.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-<div id="container"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity });
-
-  let child = document.createElement("div");
-  child.id = "child";
-  container.appendChild(child);
-
-  container.displayLock.commit().then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-update-and-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-update-and-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-update-and-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-update-and-commit.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-update-and-commit.html
deleted file mode 100644
index 7cb721ad..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-immediate-update-and-commit.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire, and calls updateAndCommit without waiting for the acquire promise.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-<div id="container"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity });
-
-  let child = document.createElement("div");
-  child.id = "child";
-  container.appendChild(child);
-
-  container.displayLock.updateAndCommit().then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe-expected.html
deleted file mode 100644
index 53621ec..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe-expected.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS</div>
-<iframe></iframe>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe.html
deleted file mode 100644
index e348b10..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!doctype HTML>
-
-<div id="log"></div>
-<iframe id="frame" srcdoc='
-  <style>
-  #container {
-    contain: style layout;
-    width: 100px;
-    height: 100px;
-    background: lightblue;
-  }
-  </style>
-  <div id="container"></div>
-'></iframe>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("frame").contentDocument.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity }).then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-added-containment-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-added-containment-expected.html
deleted file mode 100644
index de8bef3..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-added-containment-expected.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  width: 150px;
-  height: 150px;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-added-containment.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-added-containment.html
deleted file mode 100644
index 06889e3c..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-added-containment.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire on an element right after adding containment, which succeeds.
--->
-
-<style>
-#container {
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-.contained {
-  contain: style layout;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-<div id="container"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.classList = "contained";
-  container.displayLock.acquire({ timeout: Infinity }).then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-composited-layer-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-composited-layer-expected.html
deleted file mode 100644
index a1a74ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-composited-layer-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-composited-layer.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-composited-layer.html
deleted file mode 100644
index 34fe8ce9..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-composited-layer.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  will-change: transform;
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log"></div>
-<div id="container"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity }).then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); }
-  );
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-no-containment-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-no-containment-expected.html
deleted file mode 100644
index e2812ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-no-containment-expected.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log">PASS Containment requirement is not satisfied.</div>
-<div id="container"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-no-containment.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-no-containment.html
deleted file mode 100644
index b034325..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-on-no-containment.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire on an element with no containment, which fails.
--->
-
-<style>
-#container {
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log"></div>
-<div id="container"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity }).then(
-    () => { finishTest("FAIL"); },
-    (e) => { finishTest("PASS " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-rejects-after-immediate-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-rejects-after-immediate-commit-expected.html
deleted file mode 100644
index a8b4d2c..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-rejects-after-immediate-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS Lock commit was requested.</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-rejects-after-immediate-commit.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-rejects-after-immediate-commit.html
deleted file mode 100644
index de31effe..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-rejects-after-immediate-commit.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire, and calls commit without waiting for the acquire promise.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-<div id="container"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity }).then(
-    () => { finishTest("FAIL"); },
-    (e) => { finishTest("PASS " + e.message); });
-
-  let child = document.createElement("div");
-  child.id = "child";
-  container.appendChild(child);
-
-  container.displayLock.commit();
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-update-disconnect-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-update-disconnect-commit-expected.html
deleted file mode 100644
index cbafa7bb..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-update-disconnect-commit-expected.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links.html b/third_party/blink/web_tests/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links.html
deleted file mode 100644
index 3613210..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire, then tries to scroll a locked subtree element into view using anchor link navigation.
--->
-
-<style>
-.spacer {
-  width: 150px;
-  height: 3000px;
-  background: lightblue;
-}
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightgreen;
-}
-#target {
-  width: 100px;
-  height: 100px;
-  background: green;
-}
-</style>
-
-<div class="spacer"></div>
-<div id="container"><div id="target"></div></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, activatable: true }).then(() => {
-    location.href += "#target";
-    requestAnimationFrame(finishTest);
-  });
-}
-
-window.onload = () => { requestAnimationFrame(runTest); };
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/commit-immediate-acquire-resolves-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/commit-immediate-acquire-resolves-expected.html
deleted file mode 100644
index cab4e96f..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/commit-immediate-acquire-resolves-expected.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/delayed-acquire-removes-painted-output-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/delayed-acquire-removes-painted-output-expected.html
deleted file mode 100644
index 7444cebe..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/delayed-acquire-removes-painted-output-expected.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-}
-#checker {
-  width: 50px;
-  height: 50px;
-  background: green;
-}
-</style>
-
-<div id="container"></div>
-<div id="checker"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/delayed-acquire-removes-painted-output.html b/third_party/blink/web_tests/display-lock/lock-after-append/delayed-acquire-removes-painted-output.html
deleted file mode 100644
index 6d4316d..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/delayed-acquire-removes-painted-output.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!doctype HTML>
-
-<!--
-Ensures page is clean, runs an acquire after a delay.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#checker {
-  width: 50px;
-  height: 50px;
-  background: green;
-}
-</style>
-
-<div id="container"></div>
-<div id="checker"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => {
-    finishTest();
-  });
-}
-
-window.onload = () => {
-  requestAnimationFrame(() => requestAnimationFrame(runTest));
-};
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-anchor-links-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-anchor-links-expected.html
deleted file mode 100644
index 61792869..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-anchor-links-expected.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!doctype HTML>
-
-<style>
-.spacer {
-  width: 150px;
-  height: 3000px;
-  background: lightblue;
-}
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-}
-</style>
-
-<div class="spacer"></div>
-<div id="container"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-anchor-links.html b/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-anchor-links.html
deleted file mode 100644
index b1772b9..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-anchor-links.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire, then tries to scroll a locked subtree element into view using anchor link navigation.
--->
-
-<style>
-.spacer {
-  width: 150px;
-  height: 3000px;
-  background: lightblue;
-}
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightgreen;
-}
-#target {
-  width: 100px;
-  height: 100px;
-  background: green;
-}
-</style>
-
-<div class="spacer"></div>
-<div id="container"><div id="target"></div></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => {
-    location.href += "#target";
-    requestAnimationFrame(finishTest);
-  });
-}
-
-window.onload = () => { requestAnimationFrame(runTest); };
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-scroll-into-view-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-scroll-into-view-expected.html
deleted file mode 100644
index 61792869..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-scroll-into-view-expected.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!doctype HTML>
-
-<style>
-.spacer {
-  width: 150px;
-  height: 3000px;
-  background: lightblue;
-}
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-}
-</style>
-
-<div class="spacer"></div>
-<div id="container"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-scroll-into-view.html b/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-scroll-into-view.html
deleted file mode 100644
index e2e4b19..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-prevents-scroll-into-view.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire, then tries to scroll a locked subtree element into view.
--->
-
-<style>
-.spacer {
-  width: 150px;
-  height: 3000px;
-  background: lightblue;
-}
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightgreen;
-}
-#target {
-  width: 100px;
-  height: 100px;
-  background: green;
-}
-</style>
-
-<div class="spacer"></div>
-<div id="container"><div id="target"></div></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => {
-    document.getElementById("target").scrollIntoView();
-    requestAnimationFrame(finishTest);
-  });
-}
-
-window.onload = () => { requestAnimationFrame(runTest); };
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-shifted-down-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-shifted-down-expected.html
deleted file mode 100644
index 0710d7c..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-shifted-down-expected.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-}
-#spacer {
-  width: 100px;
-  height: 100px;
-  background: lightgreen;
-}
-#checker {
-  width: 100px;
-  height: 50px;
-  background: green;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="spacer"></div>
-<div id="container"></div>
-<div id="checker"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/nested-acquire-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/nested-acquire-expected.html
deleted file mode 100644
index a1a74ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/nested-acquire-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/nested-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/nested-commit-expected.html
deleted file mode 100644
index a1a74ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/nested-commit-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-and-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-and-commit-expected.html
deleted file mode 100644
index a1a74ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-and-commit-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-and-commit.html b/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-and-commit.html
deleted file mode 100644
index 5e3f17d..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-and-commit.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!doctype HTML>
-
-<style>
-.container {
-  contain: style layout;
-}
-#outer {
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-#inner {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-div > div > div {
-  width: 10px;
-  height: 10px;
-  background: red;
-}
-</style>
-
-<div id="log"></div>
-<div id="outer" class="container">
-  <div id="inner" class="container"></div>
-</div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-async function runTest() {
-  let outer = document.getElementById("outer");
-  let inner = document.getElementById("inner");
-
-  await Promise.all([
-    outer.displayLock.acquire({ timeout: Infinity }),
-    inner.displayLock.acquire({ timeout: Infinity })]);
-  // Dirty the inner layout
-  inner.appendChild(document.createElement("div"));
-  inner.displayLock.updateAndCommit().then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-expected.html
deleted file mode 100644
index a1a74ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-after-append/nested-update-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-infinite-timeout-no-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-infinite-timeout-no-commit-expected.html
deleted file mode 100644
index a1a74ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-infinite-timeout-no-commit-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-infinite-timeout-no-commit.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-infinite-timeout-no-commit.html
deleted file mode 100644
index fed86de..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-infinite-timeout-no-commit.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire, with no commit.
-The associated promise should never resolve.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.id = "container";
-  container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    document.body.appendChild(container);
-    setTimeout(() => { finishTest("PASS"); }, 100);
-  });
-}
-
-window.onload = runTest;
-</script>
-
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-timeout-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-timeout-expected.html
deleted file mode 100644
index 8f9950ebe..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-timeout-expected.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-</style>
-<div id="log">PASS if container is visible</div>
-<div id="container"></div>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-timeout.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-timeout.html
deleted file mode 100644
index b80ba1d..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-timeout.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire(), which doesn't have a corresponding commit.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.id = "container";
-
-  container.displayLock.acquire({ timeout: 100 }).then(() => {
-    document.body.appendChild(container);
-    setTimeout(() => { finishTest("PASS if container is visible"); }, 200);
-  });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-and-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-and-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-and-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-measure-remove-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-measure-remove-expected.html
deleted file mode 100644
index 4478d3b..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-measure-remove-expected.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<style>
-#spacer {
-  width: 150px;
-  height: 150px;
-  background: green;
-}
-</style>
-
-<div id="spacer"></div>
-<div id="log">0 20 40 8 8</div>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-commit-expected.html
deleted file mode 100644
index e2d291f9..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-commit-expected.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-</style>
-
-<div id="log">PASS Element is disconnected.</div>
-<div id="container"></div>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-expected.html
deleted file mode 100644
index 9f2eee17..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-expected.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS Element is disconnected.</div>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-followed-by-update-and-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-followed-by-update-and-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-followed-by-update-and-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-followed-by-update-and-commit.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-followed-by-update-and-commit.html
deleted file mode 100644
index ca6f5084..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-followed-by-update-and-commit.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
-    child.id = "child";
-    container.appendChild(child);
-
-    container.id = "container";
-    document.body.appendChild(container);
-
-    let first_promise = container.displayLock.commit();
-    let second_promise = container.displayLock.updateAndCommit();
-    Promise.all([first_promise, second_promise]).then(() => finishTest("PASS"));
-  });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-added-containment-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-added-containment-expected.html
deleted file mode 100644
index 9c57f19..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-added-containment-expected.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!doctype HTML>
-
-<style>
-.contained {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-</style>
-<div id="log">PASS</div>
-<div class="contained"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-added-containment.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-added-containment.html
deleted file mode 100644
index d1eec04..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-added-containment.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire on a container with no containment, then adds
-containment and commits.
--->
-
-<style>
-.contained {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-</style>
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-async function runTest() {
-  let container = document.createElement("div");
-  await container.displayLock.acquire({ timeout: Infinity });
-
-  container.classList = "contained";
-  document.body.appendChild(container);
-
-  container.displayLock.commit().then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); });
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-inline-fails-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-inline-fails-expected.html
deleted file mode 100644
index a9f1693..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-inline-fails-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS Containment requirement is not satisfied.</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-inline-fails.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-inline-fails.html
deleted file mode 100644
index 6efa463..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-inline-fails.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire on an inline with containment, commit fails
-since the containment isn't actually applied.
--->
-
-<style>
-#container {
-  contain: style layout;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-async function acquire() {
-  let container = document.createElement("span");
-  container.id = "container";
-  await container.displayLock.acquire({ timeout: Infinity });
-  document.body.appendChild(container);
-  container.displayLock.commit().then(
-    () => { finishTest("FAIL"); },
-    (e) => { finishTest("PASS " + e.message); });
-}
-
-window.onload = acquire;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-no-containment-fails-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-no-containment-fails-expected.html
deleted file mode 100644
index a9f1693..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-no-containment-fails-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS Containment requirement is not satisfied.</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-no-containment-fails.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-no-containment-fails.html
deleted file mode 100644
index 16d06626..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-on-no-containment-fails.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs acquire and commit on an element that doesn't have containment.
-This rejects the promise.
--->
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): This can be a testharness test.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-async function acquire() {
-  let container = document.createElement("div");
-  await container.displayLock.acquire({ timeout: Infinity });
-  document.body.appendChild(container);
-  container.displayLock.commit().then(
-    () => { finishTest("FAIL"); },
-    (e) => { finishTest("PASS " + e.message); });
-}
-
-window.onload = acquire;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected-expected.html
deleted file mode 100644
index 590a7e63..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected-expected.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"></div>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-without-acquire-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-without-acquire-expected.html
deleted file mode 100644
index cab4e96f..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-without-acquire-expected.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/display-none-ancestor-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/display-none-ancestor-expected.html
deleted file mode 100644
index 87d517d..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/display-none-ancestor-expected.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!doctype HTML>
-
-<!--
-Commit a locked element that was previously under a display:none tree.
--->
-
-<style>
-#container {
-  width: 200px;
-  height: 200px;
-  background: green;
-}
-
-#locked {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container""><div id="locked"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/multiple-acquires-all-succeed-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/multiple-acquires-all-succeed-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/multiple-acquires-all-succeed-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/multiple-update-and-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/multiple-update-and-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/multiple-update-and-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/timeout-while-disconnected-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/timeout-while-disconnected-expected.html
deleted file mode 100644
index 8f9950ebe..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/timeout-while-disconnected-expected.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-</style>
-<div id="log">PASS if container is visible</div>
-<div id="container"></div>
-
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/timeout-while-disconnected.html b/third_party/blink/web_tests/display-lock/lock-before-append/timeout-while-disconnected.html
deleted file mode 100644
index 5644d6f..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/timeout-while-disconnected.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire(), times out without ever connecting the element.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 100px;
-  height: 100px;
-  background: lightblue;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.id = "container";
-
-  container.displayLock.acquire({ timeout: 100 }).then(() => {
-    setTimeout(() => {
-      document.body.appendChild(container);
-      finishTest("PASS if container is visible");
-    }, 200);
-  });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-expected.html
deleted file mode 100644
index a1a74ba..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-commit.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-commit.html
deleted file mode 100644
index 9e56578f..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-commit.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
-    child.id = "child";
-    container.appendChild(child);
-
-    container.id = "container";
-    document.body.appendChild(container);
-
-    let first_promise = container.displayLock.updateAndCommit();
-    let second_promise = container.displayLock.commit();
-    Promise.all([first_promise, second_promise]).then(() => finishTest("PASS"));
-  });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-update-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-update-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-update-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-update.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-update.html
deleted file mode 100644
index f0d2b63..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit-followed-by-update.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
-    child.id = "child";
-    container.appendChild(child);
-
-    container.id = "container";
-    document.body.appendChild(container);
-
-    let first_promise = container.displayLock.updateAndCommit();
-    let second_promise = container.displayLock.update();
-    Promise.all([first_promise, second_promise]).then(() => finishTest("PASS"));
-  });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit.html
deleted file mode 100644
index 3f04f77..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-and-commit.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an updateAndCommit() without acquiring, which fails.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.id = "container";
-  container.displayLock.updateAndCommit().then(
-    () => { finishTest("PASS"); },
-    (e) => { finishTest("FAIL " + e.message); });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-followed-by-update-and-commit-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-followed-by-update-and-commit-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-followed-by-update-and-commit-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-followed-by-update-and-commit.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-followed-by-update-and-commit.html
deleted file mode 100644
index 0e40582..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-followed-by-update-and-commit.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
-    child.id = "child";
-    container.appendChild(child);
-
-    container.id = "container";
-    document.body.appendChild(container);
-
-    let first_promise = container.displayLock.update();
-    let second_promise = container.displayLock.updateAndCommit();
-    Promise.all([first_promise, second_promise]).then(() => finishTest("PASS"));
-  });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-together-with-commit-both-succeed-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-together-with-commit-both-succeed-expected.html
deleted file mode 100644
index 9801e1a..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-together-with-commit-both-succeed-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log">PASS</div>
-<div id="container"><div id="child"></div></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected-expected.html
deleted file mode 100644
index 4a2df4f..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected-expected.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!doctype HTML>
-
-<div id="log">PASS Element is unlocked.</div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected.html
deleted file mode 100644
index c83e15eb..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype HTML>
-
-<!--
-Runs an acquire(), then updates without connecting the element.
--->
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.id = "container";
-
-  container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    container.displayLock.update().then(
-      () => { finishTest("FAIL"); },
-      (e) => { finishTest("PASS " + e.message); });
-  });
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-without-acquire-fails-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-without-acquire-fails-expected.html
deleted file mode 100644
index 13d6a8bb..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-without-acquire-fails-expected.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype HTML>
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-</style>
-
-<div id="log">PASS Element is unlocked.</div>
-<div id="container"></div>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-without-acquire-fails.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-without-acquire-fails.html
deleted file mode 100644
index e310186..0000000
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-without-acquire-fails.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!doctype HTML>
-
-<!--
-Calls update without first calling acquire, which fails.
--->
-
-<style>
-#container {
-  contain: style layout;
-  width: 150px;
-  height: 150px;
-  background: lightblue;
-}
-#child {
-  width: 50px;
-  height: 50px;
-  background: lightgreen;
-}
-</style>
-
-<div id="log"></div>
-
-<script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest(status_string) {
-  if (document.getElementById("log").innerHTML === "")
-    document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.createElement("div");
-  container.id = "container";
-  container.displayLock.update().then(
-      () => { finishTest("FAIL"); },
-      (e) => { finishTest("PASS " + e.message); });
-  document.body.appendChild(container);
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars-expected.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars-expected.html
deleted file mode 100644
index 044462a..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars-expected.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  visibility: hidden;
-  overflow: scroll;
-  border: 10px solid black;
-}
-#sizer {
-  width: 123px;
-  height: 456px;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="sizer"></div>
-  </div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html
deleted file mode 100644
index 5fe84aaa..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  overflow: scroll;
-  border: 10px solid black;
-}
-#child {
-  width: 500px;
-  height: 500px;
-  background: red;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="child"></div>
-  </div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-expected.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-expected.html
deleted file mode 100644
index 37112ec..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-expected.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  visibility: hidden;
-  border: 10px solid black;
-}
-#sizer {
-  width: 123px;
-  height: 456px;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="sizer"></div>
-  </div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content-expected.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content-expected.html
deleted file mode 100644
index c8f3cab..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content-expected.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: min-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  visibility: hidden;
-  border: 10px solid black;
-}
-#sizer {
-  width: 123px;
-  height: 456px;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="sizer"></div>
-  </div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border.html
deleted file mode 100644
index a61afa5..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  border: 10px solid black;
-}
-#child {
-  width: 500px;
-  height: 500px;
-  background: red;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="child"></div>
-  </div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-expected.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-expected.html
deleted file mode 100644
index fd3180b..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-expected.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-}
-#sizer {
-  width: 123px;
-  height: 456px;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="sizer"></div>
-  </div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars-expected.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars-expected.html
deleted file mode 100644
index f48402a5..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars-expected.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  visibility: hidden;
-  overflow: scroll;
-}
-#sizer {
-  width: 123px;
-  height: 456px;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="sizer"></div>
-  </div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars.html
deleted file mode 100644
index a05eca8..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  overflow: scroll;
-}
-#child {
-  width: 500px;
-  height: 500px;
-  background: red;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="child"></div>
-  </div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size.html b/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size.html
deleted file mode 100644
index 1ced6176..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-}
-#child {
-  width: 500px;
-  height: 500px;
-  background: red;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="child"></div>
-  </div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-expected.html b/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-expected.html
deleted file mode 100644
index b353867..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-expected.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: column;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: horizontal-tb;
-}
-#container {
-  contain: style layout;
-}
-#child {
-  width: 12px;
-  height: 34px;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"><div id="child"></div></div>
-  <div class="item"></div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow.html b/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow.html
deleted file mode 100644
index 8f282e4..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: column;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: horizontal-tb;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  flex-grow: 3;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-  flex-grow: 1;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"></div>
-  <div class="item"></div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal.html b/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal.html
deleted file mode 100644
index 86181217..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: column;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: horizontal-tb;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"></div>
-  <div class="item"></div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-with-grow.html b/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-with-grow.html
deleted file mode 100644
index 3e3bc053..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-with-grow.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: column;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: vertical-rl;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  flex-grow: 3;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-  flex-grow: 1;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"></div>
-  <div class="item"></div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical.html b/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical.html
deleted file mode 100644
index cd11d40..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: column;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: vertical-rl;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"></div>
-  <div class="item"></div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-expected.html b/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-expected.html
deleted file mode 100644
index 5a08b6bd6..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-expected.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: horizontal-tb;
-}
-#container {
-  contain: style layout;
-}
-#child {
-  width: 12px;
-  height: 34px;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"><div id="child"></div></div>
-  <div class="item"></div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow.html b/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow.html
deleted file mode 100644
index 53554dd8..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: horizontal-tb;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  flex-grow: 3;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-  flex-grow: 1;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"></div>
-  <div class="item"></div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal.html b/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal.html
deleted file mode 100644
index d4fce2d..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: horizontal-tb;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"></div>
-  <div class="item"></div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-expected.html b/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-expected.html
deleted file mode 100644
index a8f9f707..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-expected.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: vertical-rl;
-}
-#container {
-  contain: style layout;
-}
-#child {
-  width: 12px;
-  height: 34px;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"><div id="child"></div></div>
-  <div class="item"></div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow.html b/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow.html
deleted file mode 100644
index 515ab3a5..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: vertical-rl;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  flex-grow: 3;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-  flex-grow: 1;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"></div>
-  <div class="item"></div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical.html b/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical.html
deleted file mode 100644
index 6eddd2b..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!doctype HTML>
-
-<style>
-#flexer {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-around;
-  width: 200px;
-  height: 200px;
-  background: lightgreen;
-  writing-mode: vertical-rl;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-}
-.item {
-  width: 50px;
-  height: 60px;
-  background: blue;
-}
-</style>
-
-<div id="flexer">
-  <div class="item"></div>
-  <div id="container"></div>
-  <div class="item"></div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/float-left-expected.html b/third_party/blink/web_tests/display-lock/sizing/float-left-expected.html
deleted file mode 100644
index f82ffeeb..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/float-left-expected.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  float: left;
-}
-#sizer {
-  width: 123px;
-  height: 456px;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="sizer"></div>
-  </div>
-  This is some text.
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/float-left.html b/third_party/blink/web_tests/display-lock/sizing/float-left.html
deleted file mode 100644
index 6371794..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/float-left.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  float: left;
-}
-#child {
-  width: 500px;
-  height: 500px;
-  background: red;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="child"></div>
-  </div>
-  This is some text.
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/sizing/layout-replaced-expected.html b/third_party/blink/web_tests/display-lock/sizing/layout-replaced-expected.html
deleted file mode 100644
index aa30f9a..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/layout-replaced-expected.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  border: 1px solid blue;
-  width: max-content;
-}
-img {
-  contain: style layout;
-  width: 12px;
-  height: 34px;
-  visibility: hidden;
-}
-</style>
-
-<div id="border">
-  <img src="../../images/blue-100.png">
-</div>
diff --git a/third_party/blink/web_tests/display-lock/sizing/layout-replaced.html b/third_party/blink/web_tests/display-lock/sizing/layout-replaced.html
deleted file mode 100644
index d1da5f7..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/layout-replaced.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  border: 1px solid blue;
-  width: max-content;
-}
-img {
-  contain: style layout;
-}
-</style>
-
-<div id="border">
-  <img id="element" src="../../images/blue-100.png">
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let element = document.getElementById("element");
-  element.displayLock.acquire({ timeout: Infinity, size: [12, 34] }).then(finishTest);
-}
-
-window.onload = () => requestAnimationFrame(runTest);
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/max-content-size-ignored-expected.html b/third_party/blink/web_tests/display-lock/sizing/max-content-size-ignored-expected.html
deleted file mode 100644
index fd3180b..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/max-content-size-ignored-expected.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-}
-#sizer {
-  width: 123px;
-  height: 456px;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="sizer"></div>
-  </div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/max-content-size-ignored.html b/third_party/blink/web_tests/display-lock/sizing/max-content-size-ignored.html
deleted file mode 100644
index 9f1de2a..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/max-content-size-ignored.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  width: max-content;
-}
-#child {
-  width: 500px;
-  height: 500px;
-  background: red;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="child"></div>
-  </div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/sizing/min-width-respected-expected.html b/third_party/blink/web_tests/display-lock/sizing/min-width-respected-expected.html
deleted file mode 100644
index 747259f8..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/min-width-respected-expected.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  width: 157px;
-}
-#sizer {
-  width: 123px;
-  height: 456px;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="sizer"></div>
-  </div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/min-width-respected.html b/third_party/blink/web_tests/display-lock/sizing/min-width-respected.html
deleted file mode 100644
index 041479c..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/min-width-respected.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype HTML>
-
-<style>
-#border {
-  width: max-content;
-  border: 1px solid green;
-}
-#container {
-  contain: style layout;
-  background: lightblue;
-  min-width: 157px;
-}
-#child {
-  width: 500px;
-  height: 500px;
-  background: red;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div id="child"></div>
-  </div>
-</div>
-
-<script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-function runTest() {
-  let container = document.getElementById("container");
-  container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then(finishTest);
-}
-
-window.onload = runTest;
-</script>
diff --git a/third_party/blink/web_tests/display-lock/sizing/overflow-auto-with-overflow-expected.html b/third_party/blink/web_tests/display-lock/sizing/overflow-auto-with-overflow-expected.html
deleted file mode 100644
index 21b212b..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/overflow-auto-with-overflow-expected.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<style>
-#border {
-  border: 1px solid black;
-  width: max-content;
-}
-#container {
-  contain: style layout;
-  width: 12px;
-  height: 100px;
-}
-</style>
-
-<div id="border">
-  <div id="container"></div>
-</div>
diff --git a/third_party/blink/web_tests/display-lock/sizing/overflow-auto-with-overflow.html b/third_party/blink/web_tests/display-lock/sizing/overflow-auto-with-overflow.html
deleted file mode 100644
index 3d216ff..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/overflow-auto-with-overflow.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<style>
-#border {
-  border: 1px solid black;
-  width: max-content;
-}
-#container {
-  contain: style layout;
-  height: 100px;
-  overflow: auto;
-}
-.content {
-  width: 50px;
-  height: 50px;
-  margin: 5px;
-  background: pink;
-}
-</style>
-
-<div id="border">
-  <div id="container">
-    <div class="content"></div>
-    <div class="content"></div>
-    <div class="content"></div>
-    <div class="content"></div>
-  </div>
-</div>
-
-<script>
-
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
-async function runTest() {
-  await document.getElementById("container").displayLock.acquire(
-    { timeout: Infinity, size: [12, 34] }
-  );
-  finishTest();
-}
-
-onload = () => requestAnimationFrame(runTest);
-</script>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/writing-modes-inherited-after-append-expected.html b/third_party/blink/web_tests/display-lock/sizing/writing-modes-inherited-after-append-expected.html
deleted file mode 100644
index 2ca5e8f0..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/writing-modes-inherited-after-append-expected.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<style>
-.sized {
-  width: 12px;
-  height: 34px;
-  border-style: solid;
-  border-width: 1px 2px 3px 4px;
-  padding: 5px 6px 7px 8px;
-  visibility: hidden;
-}
-.border {
-  border: 1px solid black;
-  width: max-content;
-  margin: 5px;
-}
-</style>
-
-<div class="border">
-    <div class="sized"></div>
-</div>
-<div class="border">
-    <div class="sized"></div>
-</div>
-<div class="border">
-    <div class="sized"></div>
-</div>
-<div class="border">
-    <div class="sized"></div>
-</div>
-<div class="border">
-    <div class="sized"></div>
-</div>
-
diff --git a/third_party/blink/web_tests/display-lock/sizing/writing-modes-switch-expected.html b/third_party/blink/web_tests/display-lock/sizing/writing-modes-switch-expected.html
deleted file mode 100644
index 2ca5e8f0..0000000
--- a/third_party/blink/web_tests/display-lock/sizing/writing-modes-switch-expected.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<style>
-.sized {
-  width: 12px;
-  height: 34px;
-  border-style: solid;
-  border-width: 1px 2px 3px 4px;
-  padding: 5px 6px 7px 8px;
-  visibility: hidden;
-}
-.border {
-  border: 1px solid black;
-  width: max-content;
-  margin: 5px;
-}
-</style>
-
-<div class="border">
-    <div class="sized"></div>
-</div>
-<div class="border">
-    <div class="sized"></div>
-</div>
-<div class="border">
-    <div class="sized"></div>
-</div>
-<div class="border">
-    <div class="sized"></div>
-</div>
-<div class="border">
-    <div class="sized"></div>
-</div>
-
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 d4abaf5..b43990bc 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
@@ -6385,12 +6385,6 @@
      {}
     ]
    ],
-   "pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual.html": [
-    [
-     "pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual.html",
-     {}
-    ]
-   ],
    "pointerevents/extension/pointerevent_getPredictedEvents_when_pointerlocked-manual.html": [
     [
      "pointerevents/extension/pointerevent_getPredictedEvents_when_pointerlocked-manual.html",
@@ -6457,12 +6451,6 @@
      {}
     ]
    ],
-   "pointerevents/pointerevent_boundary_events_in_capturing-manual.html": [
-    [
-     "pointerevents/pointerevent_boundary_events_in_capturing-manual.html",
-     {}
-    ]
-   ],
    "pointerevents/pointerevent_capture_suppressing_mouse-manual.html": [
     [
      "pointerevents/pointerevent_capture_suppressing_mouse-manual.html",
@@ -6493,24 +6481,12 @@
      {}
     ]
    ],
-   "pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html": [
-    [
-     "pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html",
-     {}
-    ]
-   ],
    "pointerevents/pointerevent_sequence_at_implicit_release_on_click-manual.html": [
     [
      "pointerevents/pointerevent_sequence_at_implicit_release_on_click-manual.html",
      {}
     ]
    ],
-   "pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual.html": [
-    [
-     "pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual.html",
-     {}
-    ]
-   ],
    "pointerevents/pointerevent_touch-action-button-test_touch-manual.html": [
     [
      "pointerevents/pointerevent_touch-action-button-test_touch-manual.html",
@@ -6589,12 +6565,6 @@
      {}
     ]
    ],
-   "pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual.html": [
-    [
-     "pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual.html",
-     {}
-    ]
-   ],
    "pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual.html": [
     [
      "pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual.html",
@@ -7147,6 +7117,18 @@
      {}
     ]
    ],
+   "web-share/share-files-manual.html": [
+    [
+     "web-share/share-files-manual.html",
+     {}
+    ]
+   ],
+   "web-share/share-image-manual.html": [
+    [
+     "web-share/share-image-manual.html",
+     {}
+    ]
+   ],
    "web-share/share-non-string-manual.html": [
     [
      "web-share/share-non-string-manual.html",
@@ -181869,16 +181851,6 @@
      {}
     ]
    ],
-   "mediacapture-streams/MediaDevices-IDL-all-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "mediacapture-streams/MediaDevices-IDL-enumerateDevices-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "mediacapture-streams/MediaStream-MediaElement-preload-none.https-expected.txt": [
     [
      {}
@@ -181904,11 +181876,6 @@
      {}
     ]
    ],
-   "mediacapture-streams/MediaStreamTrack-idl.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "mediacapture-streams/OWNERS": [
     [
      {}
@@ -274451,6 +274418,12 @@
      {}
     ]
    ],
+   "intersection-observer/v2/drop-shadow-filter-vertical-rl.html": [
+    [
+     "intersection-observer/v2/drop-shadow-filter-vertical-rl.html",
+     {}
+    ]
+   ],
    "intersection-observer/v2/iframe-target.html": [
     [
      "intersection-observer/v2/iframe-target.html",
@@ -290245,6 +290218,14 @@
      {}
     ]
    ],
+   "pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked.html": [
+    [
+     "pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "pointerevents/extension/pointerevent_touch-action-verification.html": [
     [
      "pointerevents/extension/pointerevent_touch-action-verification.html",
@@ -290276,6 +290257,14 @@
      }
     ]
    ],
+   "pointerevents/pointerevent_boundary_events_in_capturing.html": [
+    [
+     "pointerevents/pointerevent_boundary_events_in_capturing.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "pointerevents/pointerevent_capture_mouse.html": [
     [
      "pointerevents/pointerevent_capture_mouse.html",
@@ -290449,6 +290438,14 @@
      }
     ]
    ],
+   "pointerevents/pointerevent_releasepointercapture_events_to_original_target.html": [
+    [
+     "pointerevents/pointerevent_releasepointercapture_events_to_original_target.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html": [
     [
      "pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html",
@@ -290486,6 +290483,14 @@
      {}
     ]
    ],
+   "pointerevents/pointerevent_sequence_at_implicit_release_on_drag.html": [
+    [
+     "pointerevents/pointerevent_sequence_at_implicit_release_on_drag.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "pointerevents/pointerevent_setpointercapture_disconnected.html": [
     [
      "pointerevents/pointerevent_setpointercapture_disconnected.html",
@@ -290611,6 +290616,14 @@
      }
     ]
    ],
+   "pointerevents/pointerlock/pointerevent_movementxy_when_locked.html": [
+    [
+     "pointerevents/pointerlock/pointerevent_movementxy_when_locked.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "pointerlock/constructor.html": [
     [
      "pointerlock/constructor.html",
@@ -319250,6 +319263,14 @@
      {}
     ]
    ],
+   "webrtc/protocol/ice-state.https.html": [
+    [
+     "webrtc/protocol/ice-state.https.html",
+     {
+      "timeout": "long"
+     }
+    ]
+   ],
    "webrtc/protocol/jsep-initial-offer.https.html": [
     [
      "webrtc/protocol/jsep-initial-offer.https.html",
@@ -387275,11 +387296,11 @@
    "reftest"
   ],
   "css/css-lists/counter-set-001-ref.html": [
-   "be06ea1dc948b4f4cc9331f494dc90a5787170de",
+   "301197904a5af79eb5024bb7d97ac161e5ada3ad",
    "support"
   ],
   "css/css-lists/counter-set-001.html": [
-   "3be4c737c2ba0cc9af542413b7df7d682486efff",
+   "4e28367798ae65095b21094d2d5da777b57f4294",
    "reftest"
   ],
   "css/css-lists/counter-set-002-ref.html": [
@@ -387299,7 +387320,7 @@
    "testharness"
   ],
   "css/css-lists/li-list-item-counter-ref.html": [
-   "8340d6d7f65aebaee0cebf0317092050bb33b4e2",
+   "96ca6c1122188015d6e40e01102bdb4fecfb0567",
    "support"
   ],
   "css/css-lists/li-list-item-counter.html": [
@@ -387307,7 +387328,7 @@
    "reftest"
   ],
   "css/css-lists/li-value-counter-reset-001-ref.html": [
-   "9afb1ecfa059dda219c63d6e4d6381ac5c251d4e",
+   "6c6350c10f0f518f99d032dbf77c544b02c148e2",
    "support"
   ],
   "css/css-lists/li-value-counter-reset-001.html": [
@@ -407663,7 +407684,7 @@
    "testharness"
   ],
   "css/css-transitions/disconnected-element-001.html": [
-   "b883ce8d18d2bc14264b5c38b43a633840d0a070",
+   "dd08e559c928a4cf8fec7f4d22b991079d04eb50",
    "testharness"
   ],
   "css/css-transitions/event-dispatch.tentative-expected.txt": [
@@ -460550,6 +460571,10 @@
    "086301c44d4ef5f5dce2afb1d9ff6388f089fccf",
    "testharness"
   ],
+  "intersection-observer/v2/drop-shadow-filter-vertical-rl.html": [
+   "fc5b145e1fb43e40fdc30a2ee2e91eff77fb3293",
+   "testharness"
+  ],
   "intersection-observer/v2/iframe-target.html": [
    "3e53ee5f5814e8ef69d8454011ceafabfe8d1f17",
    "testharness"
@@ -462558,14 +462583,6 @@
    "960dc3a5ac47e9c14e8651504cb8057242f7a3be",
    "support"
   ],
-  "mediacapture-streams/MediaDevices-IDL-all-expected.txt": [
-   "ec61ea6ac5103d61fd7307f1f408717ec411759e",
-   "support"
-  ],
-  "mediacapture-streams/MediaDevices-IDL-enumerateDevices-expected.txt": [
-   "686371c97c6c682243aa1a72c061445d5b744465",
-   "support"
-  ],
   "mediacapture-streams/MediaDevices-SecureContext.html": [
    "d0fc70ca0e84d4f02970b1fa81d649b96116c1c4",
    "testharness"
@@ -462682,10 +462699,6 @@
    "e7a687d72554692fd258a9ea13b6d70273c483d9",
    "testharness"
   ],
-  "mediacapture-streams/MediaStreamTrack-idl.https-expected.txt": [
-   "124aa4268614a9981741a1f29c91ffd4a9535aa7",
-   "support"
-  ],
   "mediacapture-streams/MediaStreamTrack-init.https.html": [
    "e3e5ada541cb5c88290ae2c77c987b71bc03b8f0",
    "testharness"
@@ -462707,7 +462720,7 @@
    "testharness"
   ],
   "mediacapture-streams/idlharness.https.window.js": [
-   "441a64e3a0c84d6b0da5010ecb65e431f2763942",
+   "976d31b6609350a0ccc18a4be7764e7e3797b614",
    "testharness"
   ],
   "mediacapture-streams/idlharness.window-expected.txt": [
@@ -473487,11 +473500,11 @@
    "support"
   ],
   "permissions/interfaces.any.js": [
-   "77fa909a768fd89e2bb350ce9dc15849800a5bec",
+   "b93453886930679c557a5c4a01651150b82670d9",
    "testharness"
   ],
   "permissions/test-background-fetch-permission.html": [
-   "c3da77d9f8cc76d0cb2523e5445d2aed7c1d97ac",
+   "c824ecf1d2b47630f8ebcef3ed42c8c908c8e9eb",
    "testharness"
   ],
   "picture-in-picture/META.yml": [
@@ -473582,9 +473595,9 @@
    "6971dcecfdebf3a113ef4ef9c9e8bd7bdf88ea02",
    "testharness"
   ],
-  "pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual.html": [
-   "6efded85b4562bd960a4b5e584e68984a1ce6316",
-   "manual"
+  "pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked.html": [
+   "8e93cf32a38f04a18edd318aa5dd962edf7381c1",
+   "testharness"
   ],
   "pointerevents/extension/pointerevent_getPredictedEvents_when_pointerlocked-manual.html": [
    "eaf08d675a403aaf8bbf5a39e965af39a15d9d4e",
@@ -473650,9 +473663,9 @@
    "e860cd082bede68aa014fe36ceff011e8227e2ad",
    "testharness"
   ],
-  "pointerevents/pointerevent_boundary_events_in_capturing-manual.html": [
-   "0de4d55ed13ed67229cc4a6a0f77635fad815d01",
-   "manual"
+  "pointerevents/pointerevent_boundary_events_in_capturing.html": [
+   "1ed26eb6dcfcd728440a0eae5ddede45fe9a8dcf",
+   "testharness"
   ],
   "pointerevents/pointerevent_capture_mouse.html": [
    "d8d54db6ba302eff8e2df5c5fe13c209b3183a55",
@@ -473762,9 +473775,9 @@
    "07df04fc2046737997b70b50063825d292af90de",
    "testharness"
   ],
-  "pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html": [
-   "89f3d839f46d9982130d6aec3c9c0ed75862bfa4",
-   "manual"
+  "pointerevents/pointerevent_releasepointercapture_events_to_original_target.html": [
+   "12e31cdb234d1bbb5cc43b436415e44b12daaef2",
+   "testharness"
   ],
   "pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html": [
    "824494551671a8a15a6aa2a73a110a65beff0086",
@@ -473790,9 +473803,9 @@
    "0b93c847ed216653891d00cf55b5b00e41424b50",
    "manual"
   ],
-  "pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual.html": [
-   "982167dc5014d06c0babd3222696c8ba556d882e",
-   "manual"
+  "pointerevents/pointerevent_sequence_at_implicit_release_on_drag.html": [
+   "5f75243347a83b32a17652880c356a72bd80591a",
+   "testharness"
   ],
   "pointerevents/pointerevent_setpointercapture_disconnected.html": [
    "a7cc3e00e23f1544cdb81762025929a194df0f75",
@@ -473815,7 +473828,7 @@
    "support"
   ],
   "pointerevents/pointerevent_support.js": [
-   "e8c847b12a880a557d8d3cd69bc0bc77cf3378af",
+   "44dba450a3a2d558d3314da9413eb18a5ba9a1ff",
    "support"
   ],
   "pointerevents/pointerevent_suppress_compat_events_on_click.html": [
@@ -473918,9 +473931,9 @@
    "6d903c405e95bd140cc201b7191434fac57931c8",
    "manual"
   ],
-  "pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual.html": [
-   "ccb8c27cb59bb1732dc72c5c26b6ca2a8fdf9f5c",
-   "manual"
+  "pointerevents/pointerlock/pointerevent_movementxy_when_locked.html": [
+   "bdad97df04b2ca67fc1f92e256c979c137a4c66a",
+   "testharness"
   ],
   "pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual.html": [
    "8ac35f82856a38e887ec84ad67f5c374014905c5",
@@ -500219,7 +500232,7 @@
    "testharness"
   ],
   "web-share/resources/manual-helper.js": [
-   "2c38eab34ee51d4f50e6941b13e6743772d1fedd",
+   "e2ca229f4f9b229cfad9f84bed8b71ef96cb98d1",
    "support"
   ],
   "web-share/share-cancel-manual.html": [
@@ -500238,6 +500251,14 @@
    "d601c7df7ab7896c775d26fb1a2488fa8f827dc7",
    "manual"
   ],
+  "web-share/share-files-manual.html": [
+   "c3941bb4065b28c7f8fd4f615b8ec595ea5281a7",
+   "manual"
+  ],
+  "web-share/share-image-manual.html": [
+   "48ea4c378c194691b78d1b365999408322345a37",
+   "manual"
+  ],
   "web-share/share-non-string-manual.html": [
    "b70f8fc23d2e31e1f0ddc0aa62c7ad28917faabf",
    "manual"
@@ -503514,6 +503535,10 @@
    "1310717ccb9c035b011ff5fe5430fbd7e9f158f2",
    "support"
   ],
+  "webrtc/protocol/ice-state.https.html": [
+   "99d2a25eede4a5f2f151bc5bad6abbada8a79784",
+   "testharness"
+  ],
   "webrtc/protocol/jsep-initial-offer.https.html": [
    "50527f88dfe8f3f025cfffae91b347fdc2527a1d",
    "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/counter-set-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/counter-set-001-ref.html
index be06ea1d..3011979 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/counter-set-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/counter-set-001-ref.html
@@ -18,8 +18,8 @@
 <span>7</span><!-- "7" -->
 <span>0</span><!-- "0" -->
 <span>7</span><!-- "7" -->
-<span>8</span><!-- "8" -->
-<span>2</span><!-- "2" -->
+<span>6</span><!-- "6" -->
+<span>0</span><!-- "0" -->
 <x>
   <span>2</span><!-- "2" -->
 </x>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/counter-set-001.html b/third_party/blink/web_tests/external/wpt/css/css-lists/counter-set-001.html
index 3be4c73..4e283677 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/counter-set-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/counter-set-001.html
@@ -21,8 +21,8 @@
 <span style="counter-set: n 7"></span><!-- "7" -->
 <span style="counter-set: n"></span><!-- "0" -->
 <span style="counter-set: n 8 n 7"></span><!-- "7" -->
-<span style="counter-set: n 6; counter-increment: n 2"></span><!-- "8" -->
-<span style="counter-set: n; counter-increment: n 2"></span><!-- "2" -->
+<span style="counter-set: n 6; counter-increment: n 2"></span><!-- "6" -->
+<span style="counter-set: n; counter-increment: n 2"></span><!-- "0" -->
 <x style="counter-reset: n 9">
   <span style="counter-set: n 2"></span><!-- "2" -->
 </x>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/li-list-item-counter-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/li-list-item-counter-ref.html
index 8340d6d..96ca6c1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/li-list-item-counter-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/li-list-item-counter-ref.html
@@ -17,10 +17,10 @@
 <body>
 
 <ol><li value=0>a<li value=4>b<li value=4>c</ol>
-<ol><li value=0>a<li value=9>b<li value=9>c</ol>
-<ol><li value=-1>a<li value=3>b<li value=2>c</ol>
 <ol><li value=0>a<li value=4>b<li value=4>c</ol>
-<ol><li value=2>a<li value=6>b<li value=8>c</ol>
+<ol><li value=-1>a<li value=4>b<li value=3>c</ol>
+<ol><li value=0>a<li value=4>b<li value=4>c</ol>
+<ol><li value=2>a<li value=4>b<li value=6>c</ol>
 
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/li-value-counter-reset-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/li-value-counter-reset-001-ref.html
index 9afb1ecf..6c6350c1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/li-value-counter-reset-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/li-value-counter-reset-001-ref.html
@@ -17,9 +17,9 @@
 <body>
 
 <ol><li>a<li value=99>b</ol>
-<ol><li>a<li value=149>b</ol>
-<ol><li>a<li value=54>b</ol>
-<ol><li>a<li value=149>b</ol>
+<ol><li>a<li value=99>b</ol>
+<ol><li>a<li value=4>b</ol>
+<ol><li>a<li value=99>b</ol>
 <ol><li>a<li value=51>b</ol>
 <ol><li>a<li value=88>b</ol>
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/disconnected-element-001.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/disconnected-element-001.html
index b883ce8..dd08e55 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transitions/disconnected-element-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/disconnected-element-001.html
@@ -23,32 +23,27 @@
 
 <script>
 promise_test(async t => {
-  // Create element but do not attach it to the document
+  // Create element and remove it from the document
   const div = addDiv(t, {
     style: 'transition: background-color 100s; background-color: red',
   });
+  div.remove();
+
+  // Attach event listeners
+  div.addEventListener('transitionrun', t.step_func(() => {
+    assert_unreached('transitionrun event should not be fired');
+  }));
 
   // Resolve before-change style
   getComputedStyle(div).backgroundColor;
 
-  // Set up after-change style
+  // Set up and resolve after-change style
   div.style.backgroundColor = 'green';
+  getComputedStyle(div).backgroundColor;
 
-  assert_equals(
-    getComputedStyle(div).backgroundColor,
-    'rgb(255, 0, 0)',
-    'No transition should run'
-  );
-
-  // Wait a frame just to be sure the UA does not start the transition on the
-  // next frame.
+  // There should be no events received for the triggered transition.
   await waitForFrame();
-
-  assert_equals(
-    getComputedStyle(div).backgroundColor,
-    'rgb(255, 0, 0)',
-    'No transition should run even after waiting a frame'
-  );
+  await waitForFrame();
 }, 'Transitions do not run on an element not in the document');
 
 test(t => {
@@ -56,6 +51,7 @@
   const div = addDiv(t, {
     style: 'transition: background-color 100s; background-color: red',
   });
+  div.remove();
 
   // Resolve before-change style
   getComputedStyle(div).backgroundColor;
@@ -63,9 +59,12 @@
   // Add to document
   document.documentElement.append(div);
 
-  // Set up after-change style
+  // Set up and resolve after-change style
   div.style.backgroundColor = 'green';
+  getComputedStyle(div).backgroundColor;
 
+  // We should have jumped immediately to the after-change style rather than
+  // transitioning to it.
   assert_equals(
     getComputedStyle(div).backgroundColor,
     'rgb(0, 128, 0)',
@@ -78,7 +77,6 @@
   const div = addDiv(t, {
     style: 'transition: background-color 100s; background-color: red',
   });
-  document.documentElement.append(div);
 
   // Attach event listeners
   div.addEventListener('transitionrun', t.step_func(() => {
@@ -95,9 +93,6 @@
   div.remove();
 
   // There should be no events received for the triggered transition.
-  //
-  // (We can't verify the presence/absence of transitions by querying
-  // getComputedStyle for this case because it will return an empty string.)
   await waitForFrame();
   await waitForFrame();
 }, 'Transitions do not run for an element newly removed from the document');
@@ -107,7 +102,6 @@
   const div = addDiv(t, {
     style: 'transition: background-color 100s; background-color: red',
   });
-  document.documentElement.append(div);
 
   // Attach event listeners
   const eventWatcher = new EventWatcher(t, div, [
@@ -131,13 +125,11 @@
 promise_test(async t => {
   // Create a container element. We'll need this later.
   const container = addDiv(t);
-  document.documentElement.append(container);
 
   // Create element and attach it to the document
   const div = addDiv(t, {
     style: 'transition: background-color 100s; background-color: red',
   });
-  document.documentElement.append(div);
 
   // Attach event listeners
   const eventWatcher = new EventWatcher(t, div, [
@@ -164,15 +156,10 @@
 }, 'Transitions are canceled when an element is re-parented');
 
 promise_test(async t => {
-  // Create a container element. We'll need this later.
-  const container = addDiv(t);
-  document.documentElement.append(container);
-
   // Create element and attach it to the document
   const div = addDiv(t, {
     style: 'transition: background-color 100s; background-color: red',
   });
-  document.documentElement.append(div);
 
   // Attach event listeners
   const eventWatcher = new EventWatcher(t, div, [
@@ -187,7 +174,7 @@
 
   await eventWatcher.wait_for('transitionrun');
 
-  // Re-parent element to same container
+  // Re-parent element to same parent
   document.documentElement.append(div);
 
   await eventWatcher.wait_for('transitioncancel');
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/same-url-expected.txt b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/same-url-expected.txt
index bb4f317..8b14979e9 100644
--- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/same-url-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/same-url-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Test same-URL navigation and its effects on history assert_equals: expected 2 but got 1
+FAIL Test same-URL navigation and its effects on history assert_equals: expected 3 but got 2
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/v2/drop-shadow-filter-vertical-rl.html b/third_party/blink/web_tests/external/wpt/intersection-observer/v2/drop-shadow-filter-vertical-rl.html
new file mode 100644
index 0000000..fc5b145
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/intersection-observer/v2/drop-shadow-filter-vertical-rl.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/intersection-observer-test-utils.js"></script>
+
+<style>
+body, html {
+  margin: 0;
+}
+pre, #log {
+  position: absolute;
+  top: 150px;
+}
+#target {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+  float: left;
+}
+#occluder {
+  float: left;
+  margin-left: 10px;
+  width: 100px;
+  height: 100px;
+  background-color: blue;
+  filter: drop-shadow(-50px 0);
+  writing-mode: vertical-rl;
+}
+</style>
+
+<div id="target"></div>
+<div id="occluder"></div>
+
+<script>
+var delay = 100;
+var entries = [];
+var target;
+var occluder;
+
+runTestCycle(function() {
+  target = document.getElementById("target");
+  occluder = document.getElementById("occluder");
+  assert_true(!!target, "target exists");
+  assert_true(!!occluder, "occluder exists");
+  var observer = new IntersectionObserver(function(changes) {
+    entries = entries.concat(changes)
+  }, {trackVisibility: true, delay: delay});
+  observer.observe(target);
+  entries = entries.concat(observer.takeRecords());
+  assert_equals(entries.length, 0, "No initial notifications.");
+  runTestCycle(step0, "First rAF.", delay);
+}, "IntersectionObserverV2 in a single document using the implicit root, with an occluding element.", delay);
+
+function step0() {
+  // Occluding elements with opacity=0 should not affect target visibility.
+  occluder.style.opacity = "0";
+  runTestCycle(step2, "occluder.style.opacity = 0", delay);
+
+  // First notification should report occlusion due to drop shadow filter.
+  checkLastEntry(entries, 0, [0, 100, 0, 100, 0, 100, 0, 100, 0, 800, 0, 600, true, false]);
+}
+
+function step2() {
+  checkLastEntry(entries, 1, [0, 100, 0, 100, 0, 100, 0, 100, 0, 800, 0, 600, true, true]);
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked.html
similarity index 89%
rename from third_party/blink/web_tests/external/wpt/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked.html
index 6efded8..8e93cf32 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="../pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <script type="text/javascript" src="../pointerevent_support.js"></script>
         <style>
           #testContainer {
@@ -38,6 +41,9 @@
                         });
                     }
                 });
+
+                // Inject mouse inputs.
+                pointerDragInTarget('mouse', div1, 'right');
             }
         </script>
     </head>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_boundary_events_in_capturing-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_boundary_events_in_capturing.html
similarity index 91%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_boundary_events_in_capturing-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_boundary_events_in_capturing.html
index 0de4d55..1ed26eb 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_boundary_events_in_capturing-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_boundary_events_in_capturing.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <!-- Additional helper script for common checks across event types -->
         <script type="text/javascript" src="pointerevent_support.js"></script>
         <script>
@@ -67,6 +70,13 @@
                         }
                     });
                 });
+
+                // Inject pointer inputs.
+                pointerDragInTarget('mouse', target0, 'right').then(function() {
+                    return pointerDragInTarget('touch', target0, 'right');
+                }).then(function() {
+                    return pointerDragInTarget('pen', target0, 'right');
+                });
             }
         </script>
     </head>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_events_to_original_target.html
similarity index 92%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_events_to_original_target.html
index 89f3d839..12e31cdb 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_events_to_original_target.html
@@ -8,6 +8,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <!-- Additional helper script for common checks across event types -->
         <script type="text/javascript" src="pointerevent_support.js"></script>
         <script type="text/javascript">
@@ -111,6 +114,13 @@
                     on_event(target0, All_Pointer_Events[i], targetEventHandler);
                     on_event(listener, All_Pointer_Events[i], listenerEventHandler);
                 }
+
+                // Inject pointer inputs.
+                pointerDragInTarget('mouse', target0, 'right').then(function() {
+                    return pointerDragInTarget('touch', target0, 'right');
+                }).then(function() {
+                    return pointerDragInTarget('pen', target0, 'right');
+                });
             }
         </script>
     </head>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_sequence_at_implicit_release_on_drag.html
similarity index 88%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_sequence_at_implicit_release_on_drag.html
index 982167d..5f752433 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_sequence_at_implicit_release_on_drag.html
@@ -8,6 +8,9 @@
     <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
     <script src="/resources/testharness.js"></script>
     <script src="/resources/testharnessreport.js"></script>
+    <script src="/resources/testdriver.js"></script>
+    <script src="/resources/testdriver-actions.js"></script>
+    <script src="/resources/testdriver-vendor.js"></script>
     <script type="text/javascript" src="pointerevent_support.js"></script>
     <script type="text/javascript">
       var detected_pointertypes = {};
@@ -23,6 +26,7 @@
       function run() {
         var test_pointer_event = setup_pointerevent_test("Event sequence at implicit release on drag", ["touch"]);
 
+        var button = document.getElementById("done");
         on_event(document.getElementById("done"), "click", function() {
           test_pointer_event.step(function () {
             var expected_events = "pointercancel, lostpointercapture, pointerout, pointerleave";
@@ -48,6 +52,11 @@
             }
           });
         });
+
+        // Inject touch inputs.
+        pointerDragInTarget("touch", target, 'right').then(function() {
+          return touchTapInTarget(button);
+        });
       }
     </script>
     <style>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js
index e8c847b..44dba45 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js
@@ -285,3 +285,42 @@
                    .pointerUp()
                    .send();
 }
+
+function touchTapInTarget(target) {
+    return new test_driver.Actions()
+                   .addPointer("pointer1", "touch")
+                   .pointerMove(0, 0, {origin: target})
+                   .pointerDown()
+                   .pointerUp()
+                   .send();
+}
+
+function pointerDragInTarget(pointerType, target, direction) {
+    var x_delta = 0;
+    var y_delta = 0;
+    if (direction == "down") {
+        x_delta = 0;
+        y_delta = 10;
+    } else if (direction == "up") {
+        x_delta = 0;
+        y_delta = -10;
+    } else if (direction == "right") {
+        x_delta = 10;
+        y_delta = 0;
+    } else if (direction == "left") {
+        x_delta = -10;
+        y_delta = 0;
+    } else {
+        throw("drag direction '" + direction + "' is not expected, direction should be 'down', 'up', 'left' or 'right'");
+    }
+    var pointerId = pointerType + "Pointer1";
+    return new test_driver.Actions()
+                   .addPointer(pointerId, pointerType)
+                   .pointerMove(0, 0, {origin: target})
+                   .pointerDown()
+                   .pointerMove(x_delta, y_delta, {origin: target})
+                   .pointerMove(2 * x_delta, 2 * y_delta, {origin: target})
+                   .pointerMove(3 * x_delta, 3 * y_delta, {origin: target})
+                   .pointerUp()
+                   .send();
+}
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked.html
similarity index 92%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked.html
index ccb8c27..bdad97df 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="/external/wpt/pointerevents/pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <script type="text/javascript" src="../pointerevent_support.js"></script>
         <style>
           #testContainer {
@@ -59,6 +62,9 @@
                         test_pointerEvent.done();
                     }
                 });
+
+                // Inject mouse inputs.
+                pointerDragInTarget('mouse', target, 'right');
             }
         </script>
     </head>
diff --git a/third_party/blink/web_tests/external/wpt/portals/portals-host-post-message.sub.html b/third_party/blink/web_tests/external/wpt/portals/portals-host-post-message.sub.html
index a142f55..a19715eb 100644
--- a/third_party/blink/web_tests/external/wpt/portals/portals-host-post-message.sub.html
+++ b/third_party/blink/web_tests/external/wpt/portals/portals-host-post-message.sub.html
@@ -9,10 +9,10 @@
       var portal = document.createElement("portal");
       portal.src = portalSrc;
       return new Promise((resolve, reject) => {
-        portal.addEventListener("message", e => {
+        portal.onmessage = e => {
           if (e.data == "loaded")
             resolve(portal);
-        });
+        };
         document.body.appendChild(portal);
       });
     }
@@ -56,6 +56,87 @@
     }, "Message received from cross-origin portal host with target origin correctly specified");
 
     promise_test(async () => {
+      var message = {
+        prop1: "value1",
+        prop2: 2.5,
+        prop3: [1, 2, "3"],
+        prop4: {
+          prop4_1: "value4_1"
+        }
+      };
+      var {data} = await createPortalAndLoopMessage(
+        "resources/portal-host-post-message.sub.html", [message]);
+      assert_object_equals(data, message);
+      var {data} = await createPortalAndLoopMessage(crossOriginUrl,
+                                                    [message, "*"]);
+      assert_object_equals(data, message);
+    }, "postMessage with object message");
+
+    promise_test(async () => {
+      function checkPort(port) {
+        return new Promise((resolve, reject) => {
+          var channel = new MessageChannel();
+          channel.port1.onmessage = resolve;
+          port.postMessage("sending port", [channel.port2]);
+        });
+      }
+
+      var {ports} = await createPortalAndLoopMessage(
+        "resources/portal-host-post-message.sub.html",
+        {type: "message-port"});
+      await checkPort(ports[0]);
+
+      var {ports} = await createPortalAndLoopMessage(
+        crossOriginUrl,
+        {type: "message-port"});
+      await checkPort(ports[0]);
+    }, "postMessage with message ports");
+
+    promise_test(async () => {
+      var {data} = await createPortalAndLoopMessage(
+        "resources/portal-host-post-message.sub.html", {
+          type: "array-buffer-without-transfer",
+          array: [0, 1, 2, 3, 4]
+      });
+      assert_array_equals([0, 1, 2, 3, 4], new Int8Array(data.arrayBuffer));
+
+      var {data} = await createPortalAndLoopMessage(crossOriginUrl, {
+          type: "array-buffer-without-transfer",
+          array: [0, 1, 2, 3, 4]
+      });
+      assert_array_equals([0, 1, 2, 3, 4], new Int8Array(data.arrayBuffer));
+    }, "postMessage with array buffer without transfer");
+
+    promise_test(async () => {
+      var {data} = await createPortalAndLoopMessage(
+        "resources/portal-host-post-message.sub.html", {
+          type: "array-buffer-with-transfer",
+          array: [0, 1, 2, 3, 4]
+      });
+      assert_array_equals([0, 1, 2, 3, 4], new Int8Array(data.arrayBuffer));
+
+      var {data} = await createPortalAndLoopMessage(crossOriginUrl, {
+          type: "array-buffer-with-transfer",
+          array: [0, 1, 2, 3, 4]
+      });
+      assert_array_equals([0, 1, 2, 3, 4], new Int8Array(data.arrayBuffer));
+    }, "postMessage with array buffer with transfer");
+
+    promise_test(async () => {
+      var {data} = await createPortalAndLoopMessage(
+        "resources/portal-host-post-message.sub.html",
+        {type: "invalid-message"});
+      assert_equals(data.errorType, "DataCloneError");
+    }, "postMessage should throw error when serialization fails");
+
+    promise_test(async () => {
+      var {data} = await createPortalAndLoopMessage(
+        "resources/portal-host-post-message.sub.html",
+        {type: "invalid-port"});
+      assert_equals(data.errorType, "TypeError");
+    }, "postMessage with invalid transferable should throw error");
+
+    promise_test(async () => {
        var receiveMessage = new Promise((resolve, reject) => {
          var bc = new BroadcastChannel("portal-host-post-message-after-activate");
          bc.onmessage = e => { resolve(e); };
diff --git a/third_party/blink/web_tests/external/wpt/portals/resources/portal-host-post-message.sub.html b/third_party/blink/web_tests/external/wpt/portals/resources/portal-host-post-message.sub.html
index 8df9830..06d4282 100644
--- a/third_party/blink/web_tests/external/wpt/portals/resources/portal-host-post-message.sub.html
+++ b/third_party/blink/web_tests/external/wpt/portals/resources/portal-host-post-message.sub.html
@@ -1,7 +1,52 @@
 <!DOCTYPE html>
 <script>
+  function postMessageWithMessagePorts() {
+    var channel = new MessageChannel();
+    channel.port1.onmessage = e => {
+      e.ports[0].postMessage("received");
+    }
+    window.portalHost.postMessage("sending port", "*", [channel.port2]);
+  }
+
+  function postMessageWithArrayBuffer(array, withTransfer) {
+    var arrayBuffer = new Int8Array(array).buffer;
+    if (withTransfer) {
+      window.portalHost.postMessage({arrayBuffer}, "*", [arrayBuffer]);
+    } else {
+      window.portalHost.postMessage({arrayBuffer}, "*");
+    }
+  }
+
+  function postMessageAndCatchException(...params) {
+    try {
+      window.portalHost.postMessage(...params);
+    } catch (e) {
+      window.portalHost.postMessage({errorType: e.name}, "*");
+    }
+  }
+
   window.portalHost.postMessage("loaded", "*");
   window.portalHost.addEventListener("message", e => {
+    if (e.data.type) {
+      var type = e.data.type;
+      switch (type) {
+        case "message-port":
+          postMessageWithMessagePorts();
+          return;
+        case "array-buffer-without-transfer":
+          postMessageWithArrayBuffer(e.data.array, false);
+          return;
+        case "array-buffer-with-transfer":
+          postMessageWithArrayBuffer(e.data.array, true);
+          return;
+        case "invalid-message":
+          postMessageAndCatchException(document.body, "*");
+          return;
+        case "invalid-port":
+          postMessageAndCatchException("", "*", [null]);
+          return;
+      }
+    }
     window.portalHost.postMessage(...e.data);
   });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/portals/resources/portal-post-message-portal.html b/third_party/blink/web_tests/external/wpt/portals/resources/portal-post-message-portal.html
index 539048c..1dae5d1 100644
--- a/third_party/blink/web_tests/external/wpt/portals/resources/portal-post-message-portal.html
+++ b/third_party/blink/web_tests/external/wpt/portals/resources/portal-post-message-portal.html
@@ -3,7 +3,7 @@
   var bc = new BroadcastChannel("portals-post-message");
   bc.postMessage("loaded");
   bc.close();
-  window.portalHost.addEventListener("message", e => {
+  window.portalHost.onmessage = e => {
     var message = {
       origin: e.origin,
       data: e.data,
@@ -30,5 +30,5 @@
     bc = new BroadcastChannel("portals-post-message");
     bc.postMessage(message);
     bc.close();
-  });
+  };
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/web-share/resources/manual-helper.js b/third_party/blink/web_tests/external/wpt/web-share/resources/manual-helper.js
index 2c38eab3..e2ca229 100644
--- a/third_party/blink/web_tests/external/wpt/web-share/resources/manual-helper.js
+++ b/third_party/blink/web_tests/external/wpt/web-share/resources/manual-helper.js
@@ -28,7 +28,7 @@
 // Sets up the page for running manual tests. Automatically creates the
 // instructions (based on the parameters) and the share button.
 function setupManualShareTest(expected_share_data) {
-  const {title, text, url} = expected_share_data;
+  const {title, text, url, files} = expected_share_data;
   let [instruction, list] = setupManualShareTestCommon();
   let item = document.createElement('li');
   list.appendChild(item);
@@ -50,6 +50,27 @@
   item = document.createElement('li');
   list.appendChild(item);
   item.innerText = `url = "${url}"`;
+  if (files) {
+    item = document.createElement('li');
+    list.appendChild(item);
+    item.innerText = `files = ${files.length} file(s)`;
+    for (let file of files) {
+      const div = document.createElement('div');
+      if (file.type.startsWith('text/')) {
+        const reader = new FileReader();
+        reader.onload = () => {
+          div.textContent = reader.result;
+        };
+        reader.readAsText(file);
+      } else if (file.type.startsWith('image/')) {
+        const image = document.createElement('img');
+        image.src = URL.createObjectURL(file);
+        image.alt = file.name;
+        div.appendChild(image);
+      }
+      item.appendChild(div);
+    }
+  }
 }
 
 function setupManualShareTestRequiringCancellation() {
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-files-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-files-manual.html
new file mode 100644
index 0000000..c3941bb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/web-share/share-files-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>WebShare Test: Share multiple files</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="resources/manual-helper.js"></script>
+  </head>
+  <body>
+    <script>
+        setup({explicit_timeout: true});
+
+        const options = {type: 'text/plain'};
+        const first = new File(['one'], 'first.txt', options);
+        const second = new File(['two'], 'second.txt', options);
+        const third = new File(['three'], 'third.txt', options);
+        const fourth = new File(['four'], 'fourth.txt', options);
+        const fifth = new File(['five'], 'fifth.txt', options);
+        const data = {
+          title: 'Counting to 5',
+          text: 'Here are the numbers',
+          url: 'https://example.com/',
+          files: [first, second, third, fourth, fifth]
+        };
+        setupManualShareTest(data);
+        callWhenButtonClicked(() => navigator.share(data));
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-image-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-image-manual.html
new file mode 100644
index 0000000..48ea4c37
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/web-share/share-image-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>WebShare Test: Share single image file</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="resources/manual-helper.js"></script>
+  </head>
+  <body>
+    <script>
+        setup({explicit_timeout: true});
+
+        const fileBits = [
+          '<svg xmlns="http://www.w3.org/2000/svg" width="80px" height="80px">',
+          '<circle cx="40" cy="40" r="28" fill="lime" />',
+          '</svg>'
+        ];
+        const fileName = 'circle.svg';
+        const options = {type: 'image/svg+xml'};
+        const file = new File(fileBits, fileName, options);
+        setupManualShareTest({title: '', text: '', url: '', files: [file]});
+        callWhenButtonClicked(() => navigator.share({files: [file]}));
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/protocol/ice-state.https.html b/third_party/blink/web_tests/external/wpt/webrtc/protocol/ice-state.https.html
new file mode 100644
index 0000000..99d2a25e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webrtc/protocol/ice-state.https.html
@@ -0,0 +1,130 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>RTCPeerConnection Failed State</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../RTCPeerConnection-helper.js"></script>
+<script>
+'use strict';
+
+// Tests for correct behavior of ICE state.
+
+// SDP copied from JSEP Example 7.1
+// It contains two media streams with different ufrags, and bundle
+// turned on.
+const kSdp = `v=0
+o=- 4962303333179871722 1 IN IP4 0.0.0.0
+s=-
+t=0 0
+a=ice-options:trickle
+a=group:BUNDLE a1 v1
+a=group:LS a1 v1
+m=audio 10100 UDP/TLS/RTP/SAVPF 96 0 8 97 98
+c=IN IP4 203.0.113.100
+a=mid:a1
+a=sendrecv
+a=rtpmap:96 opus/48000/2
+a=rtpmap:0 PCMU/8000
+a=rtpmap:8 PCMA/8000
+a=rtpmap:97 telephone-event/8000
+a=rtpmap:98 telephone-event/48000
+a=maxptime:120
+a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
+a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
+a=msid:47017fee-b6c1-4162-929c-a25110252400 f83006c5-a0ff-4e0a-9ed9-d3e6747be7d9
+a=ice-ufrag:ETEn
+a=ice-pwd:OtSK0WpNtpUjkY4+86js7ZQl
+a=fingerprint:sha-256 19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04:BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
+a=setup:actpass
+a=dtls-id:1
+a=rtcp:10101 IN IP4 203.0.113.100
+a=rtcp-mux
+a=rtcp-rsize
+m=video 10102 UDP/TLS/RTP/SAVPF 100 101
+c=IN IP4 203.0.113.100
+a=mid:v1
+a=sendrecv
+a=rtpmap:100 VP8/90000
+a=rtpmap:101 rtx/90000
+a=fmtp:101 apt=100
+a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
+a=rtcp-fb:100 ccm fir
+a=rtcp-fb:100 nack
+a=rtcp-fb:100 nack pli
+a=msid:47017fee-b6c1-4162-929c-a25110252400 f30bdb4a-5db8-49b5-bcdc-e0c9a23172e0
+a=ice-ufrag:BGKk
+a=ice-pwd:mqyWsAjvtKwTGnvhPztQ9mIf
+a=fingerprint:sha-256 19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04:BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
+a=setup:actpass
+a=dtls-id:1
+a=rtcp:10103 IN IP4 203.0.113.100
+a=rtcp-mux
+a=rtcp-rsize
+`;
+
+// Returns a promise that resolves when |pc.iceConnectionState| is in one of the
+// wanted states, and rejects if it is in one of the unwanted states.
+// This is a variant of the function in RTCPeerConnection-helper.js.
+function waitForIceStateChange(pc, wantedStates, unwantedStates=[]) {
+  return new Promise((resolve, reject) => {
+    if (wantedStates.includes(pc.iceConnectionState)) {
+      resolve();
+      return;
+    } else if (unwantedStates.includes(pc.iceConnectionState)) {
+      reject('Unexpected state encountered: ' + pc.iceConnectionState);
+      return;
+    }
+    pc.addEventListener('iceconnectionstatechange', () => {
+      if (wantedStates.includes(pc.iceConnectionState)) {
+        resolve();
+      } else if (unwantedStates.includes(pc.iceConnectionState)) {
+        reject('Unexpected state encountered: ' + pc.iceConnectionState);
+      }
+    });
+  });
+}
+
+promise_test(async t => {
+  const pc1 = new RTCPeerConnection();
+  const pc2 = new RTCPeerConnection();
+  t.add_cleanup(() => pc1.close());
+  t.add_cleanup(() => pc2.close());
+  let [track, streams] = await getTrackFromUserMedia('video');
+  const sender = pc1.addTrack(track);
+  exchangeIceCandidates(pc1, pc2);
+  await doSignalingHandshake(pc1, pc2);
+  await waitForIceStateChange(pc1, ['connected']);
+}, 'PC should enter connected state when candidates are sent');
+
+promise_test(async t => {
+  const pc1 = new RTCPeerConnection();
+  t.add_cleanup(() => pc1.close());
+  let [track, streams] = await getTrackFromUserMedia('video');
+  const sender = pc1.addTrack(track);
+  const offer = await pc1.createOffer();
+  assert_greater_than_equal(offer.sdp.search('a=ice-options:trickle'), 0);
+}, 'PC should generate offer with a=ice-options:trickle');
+
+promise_test(async t => {
+  const pc1 = new RTCPeerConnection();
+  t.add_cleanup(() => pc1.close());
+  await pc1.setRemoteDescription({type: 'offer', sdp: kSdp});
+  const answer = await pc1.createAnswer();
+  await pc1.setLocalDescription(answer);
+  assert_greater_than_equal(answer.sdp.search('a=ice-options:trickle'), 0);
+  // When we use trickle ICE, and don't signal end-of-caniddates, we
+  // expect failure to result in 'disconnected' state rather than 'failed'.
+  const stateWaiter = waitForIceStateChange(pc1, ['disconnected'],
+                                            ['failed']);
+  // Add a bogus candidate. The candidate is drawn from the
+  // IANA "test-net-3" pool (RFC5737), so is guaranteed not to respond.
+  const candidateStr1 =
+      'candidate:1 1 udp 2113929471 203.0.113.100 10100 typ host';
+  await pc1.addIceCandidate({candidate: candidateStr1,
+                             sdpMid: 'a1',
+                             usernameFragment: 'ETEn'});
+  await stateWaiter;
+}, 'PC should enter disconnected state when a failing candidate is sent');
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual-automation.js
deleted file mode 100644
index 6d50711..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/extension/pointerevent_getCoalescedEvents_when_pointerlocked-manual-automation.js
+++ /dev/null
@@ -1,5 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return pointerDragInTarget('mouse', '#target', 'left');
-}
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_boundary_events_in_capturing-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_boundary_events_in_capturing-manual-automation.js
deleted file mode 100644
index 6cd7425..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_boundary_events_in_capturing-manual-automation.js
+++ /dev/null
@@ -1,9 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return pointerDragInTarget('mouse', '#target0', 'right').then(function() {
-    return pointerDragInTarget('touch', '#target0', 'right');
-  }).then(function() {
-    return pointerDragInTarget('pen', '#target0', 'right');
-  });
-}
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual-automation.js
deleted file mode 100644
index 6cd7425..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual-automation.js
+++ /dev/null
@@ -1,9 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return pointerDragInTarget('mouse', '#target0', 'right').then(function() {
-    return pointerDragInTarget('touch', '#target0', 'right');
-  }).then(function() {
-    return pointerDragInTarget('pen', '#target0', 'right');
-  });
-}
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual-automation.js
deleted file mode 100644
index c0b9fbf..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual-automation.js
+++ /dev/null
@@ -1,7 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return pointerDragInTarget('touch', '#target', 'right').then(function() {
-    return touchTapInTarget('#done');
-  });
-}
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual-automation.js
deleted file mode 100644
index 684858a..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerlock/pointerevent_movementxy_when_locked-manual-automation.js
+++ /dev/null
@@ -1,5 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return pointerDragInTarget('mouse', '#target', 'right');
-}
diff --git a/third_party/blink/web_tests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification.html
index 6016ae4..2e6f274 100644
--- a/third_party/blink/web_tests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification.html
@@ -11,9 +11,9 @@
 async_test((t) => {
     var testInput = document.getElementById("test");
     var expected = [
-        [ "Focus", "Month", "10" ],
-        [ "Focus", "Day", "09" ],
-        [ "Focus", "Year", "2012" ],
+        [ "Focus", "Month", "10", "\t" ],
+        [ "Focus", "Day", "09", "4"],
+        [ "Focus", "Year", "2012", "ArrowUp" ],
         [ "ValueChanged", "Day", "04" ],
         [ "ValueChanged", "Day", "04" ],
         [ "ValueChanged", "Year", "2013" ],
@@ -26,15 +26,14 @@
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
+                if (next_expectation.length > 3)
+                    eventSender.keyDown(next_expectation[3]);
             }
             if (expected.length === 0)
                 t.done();
         }));
 
     testInput.focus();
-    eventSender.keyDown('\t');
-    eventSender.keyDown('4');
-    eventSender.keyDown('ArrowUp');
 
     window.setTimeout(function() {
         assert_unreached("Did not receive all accessibility notifications");
diff --git a/third_party/blink/web_tests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification.html
index 255b11e..b09c0453 100644
--- a/third_party/blink/web_tests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification.html
@@ -10,15 +10,15 @@
 async_test((t) => {
     var testInput = document.getElementById('test');
     var expected = [
-        [ "Focus", "Month", "10" ],
-        [ "Focus", "Day", "09" ],
-        [ "Focus", "Year", "2012" ],
+        [ "Focus", "Month", "10", "\t" ],
+        [ "Focus", "Day", "09", "4" ],
+        [ "Focus", "Year", "2012", "ArrowUp" ],
         [ "ValueChanged", "Day", "04" ],
         [ "ValueChanged", "Day", "04" ],
         [ "ValueChanged", "Year", "2013" ],
-        [ "ValueChanged", "Year", "2013" ],
-        [ "Focus", "Hours", "12" ],
-        [ "Focus", "Minutes", "34" ],
+        [ "ValueChanged", "Year", "2013", "\t" ],
+        [ "Focus", "Hours", "12", "2" ],
+        [ "Focus", "Minutes", "34", "ArrowDown" ],
         [ "ValueChanged", "Hours", "02" ],
         [ "ValueChanged", "Hours", "02" ],
         [ "ValueChanged", "Minutes", "33" ],
@@ -32,18 +32,14 @@
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
+                if (next_expectation.length > 3)
+                    eventSender.keyDown(next_expectation[3]);
             }
             if (expected.length === 0)
                 t.done();
         }));
 
     testInput.focus();
-    eventSender.keyDown('\t');
-    eventSender.keyDown('4');
-    eventSender.keyDown('ArrowUp');
-    eventSender.keyDown('\t');
-    eventSender.keyDown('2');
-    eventSender.keyDown('ArrowDown');
 
     window.setTimeout(function() {
         assert_unreached("Did not receive all accessibility notifications");
diff --git a/third_party/blink/web_tests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification.html
index 4849cb3..cebf0de 100644
--- a/third_party/blink/web_tests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification.html
@@ -10,10 +10,10 @@
 async_test((t) => {
     var testInput = document.getElementById('test');
     var expected = [
-        [ "Focus", "Month", "October" ],
-        [ "Focus", "Year", "2012" ],
+        [ "Focus", "Month", "October", "\t" ],
+        [ "Focus", "Year", "2012", "4" ],
         [ "ValueChanged", "Year", "0004" ],
-        [ "ValueChanged", "Year", "0004" ],
+        [ "ValueChanged", "Year", "0004", "ArrowUp" ],
         [ "ValueChanged", "Year", "0005" ],
         [ "ValueChanged", "Year", "0005" ] ];
 
@@ -25,15 +25,14 @@
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
+                if (next_expectation.length > 3)
+                    eventSender.keyDown(next_expectation[3]);
             }
             if (expected.length === 0)
                 t.done();
         }));
 
     testInput.focus();
-    eventSender.keyDown('\t');
-    eventSender.keyDown('4');
-    eventSender.keyDown('ArrowUp');
 
     window.setTimeout(function() {
         assert_unreached("Did not receive all accessibility notifications");
diff --git a/third_party/blink/web_tests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
index 59b833e8..5c6bef3d 100644
--- a/third_party/blink/web_tests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
@@ -10,10 +10,10 @@
 async_test((t) => {
     var testInput = document.getElementById('test');
     var expected = [
-        [ "Focus", "Hours", "12" ],
-        [ "Focus", "Minutes", "34" ],
+        [ "Focus", "Hours", "12", "\t" ],
+        [ "Focus", "Minutes", "34", "4" ],
         [ "ValueChanged", "Minutes", "04" ],
-        [ "ValueChanged", "Minutes", "04" ],
+        [ "ValueChanged", "Minutes", "04", "ArrowUp" ],
         [ "ValueChanged", "Minutes", "05" ],
         [ "ValueChanged", "Minutes", "05" ] ];
 
@@ -24,15 +24,14 @@
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
+                if (next_expectation.length > 3)
+                    eventSender.keyDown(next_expectation[3]);
             }
             if (expected.length === 0)
                 t.done();
         }));
 
     testInput.focus();
-    eventSender.keyDown('\t');
-    eventSender.keyDown('4');
-    eventSender.keyDown('ArrowUp');
 
     window.setTimeout(function() {
         assert_unreached("Did not receive all accessibility notifications");
diff --git a/third_party/blink/web_tests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html b/third_party/blink/web_tests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
index a72e6da..60f3f2f 100644
--- a/third_party/blink/web_tests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/blink/web_tests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
@@ -10,10 +10,10 @@
 async_test((t) => {
     var testInput = document.getElementById('test');
     var expected = [
-        [ "Focus", "Week", "10" ],
-        [ "Focus", "Year", "2012" ],
+        [ "Focus", "Week", "10", "\t" ],
+        [ "Focus", "Year", "2012", "4" ],
         [ "ValueChanged", "Year", "0004" ],
-        [ "ValueChanged", "Year", "0004" ],
+        [ "ValueChanged", "Year", "0004", "ArrowUp" ],
         [ "ValueChanged", "Year", "0005" ],
         [ "ValueChanged", "Year", "0005" ] ];
 
@@ -24,15 +24,14 @@
                 assert_equals(notification, next_expectation[0]);
                 assert_equals(element.name.trim(), next_expectation[1]);
                 assert_equals(element.valueDescription.substr(20), next_expectation[2]);
+                if (next_expectation.length > 3)
+                    eventSender.keyDown(next_expectation[3]);
             }
             if (expected.length === 0)
                 t.done();
         }));
 
     testInput.focus();
-    eventSender.keyDown('\t');
-    eventSender.keyDown('4');
-    eventSender.keyDown('ArrowUp');
 
     window.setTimeout(function() {
         assert_unreached("Did not receive all accessibility notifications");
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
index ac9e7984..11af00d0 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
@@ -12,34 +12,14 @@
           "reason": "geometry"
         },
         {
-          "object": "LayoutSVGEllipse circle",
+          "object": "LayoutSVGRoot svg",
           "rect": [47, 111, 324, 324],
-          "reason": "SVG resource change"
+          "reason": "paint property change"
         },
         {
           "object": "LayoutSVGRoot svg",
-          "rect": [47, 392, 324, 43],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [47, 111, 324, 43],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [110, 154, 261, 238],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGEllipse circle",
-          "rect": [8, 154, 170, 238],
-          "reason": "SVG resource change"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [8, 154, 39, 238],
-          "reason": "incremental"
+          "rect": [8, 154, 102, 238],
+          "reason": "paint property change"
         }
       ]
     }
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.txt
new file mode 100644
index 0000000..48013f28
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.txt
@@ -0,0 +1,23 @@
+{
+  "layers": [
+    {
+      "name": "Scrolling background of LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "LayoutSVGRoot svg id='svg'",
+          "rect": [7, 7, 102, 115],
+          "reason": "paint property change"
+        },
+        {
+          "object": "LayoutSVGRoot svg id='svg'",
+          "rect": [7, 7, 3, 115],
+          "reason": "paint property change"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
index 47efbde..9187dd86 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
@@ -23,34 +23,14 @@
           "reason": "geometry"
         },
         {
-          "object": "LayoutSVGEllipse circle",
+          "object": "LayoutSVGRoot svg",
           "rect": [47, 111, 324, 324],
-          "reason": "SVG resource change"
+          "reason": "paint property change"
         },
         {
           "object": "LayoutSVGRoot svg",
-          "rect": [47, 392, 324, 43],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [47, 111, 324, 43],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [110, 154, 261, 238],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGEllipse circle",
-          "rect": [8, 154, 170, 238],
-          "reason": "SVG resource change"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [8, 154, 39, 238],
-          "reason": "incremental"
+          "rect": [8, 154, 102, 238],
+          "reason": "paint property change"
         }
       ]
     }
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-2/force-pseudo-state-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/styles-2/force-pseudo-state-expected.txt
index 9477dd0..36d14a5 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-2/force-pseudo-state-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/styles-2/force-pseudo-state-expected.txt
@@ -65,10 +65,10 @@
 
 [expanded] 
 :focus { (user agent stylesheet)
-    outline: -webkit-focus-ring-color auto 5px;
+    outline: -webkit-focus-ring-color auto 1px;
         outline-color: -webkit-focus-ring-color;
         outline-style: auto;
-        outline-width: 5px;
+        outline-width: 1px;
 
 [expanded] 
 div { (user agent stylesheet)
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-events-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-events-expected.txt
new file mode 100644
index 0000000..e2aa1ae7
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-events-expected.txt
@@ -0,0 +1,254 @@
+Tests that the expected events are received.
+Background Fetch Success:
+[
+    [0] : {
+        eventMetadata : [
+            [0] : {
+                key : Start Paused
+                value : No
+            }
+            [1] : {
+                key : Total Requests
+                value : 1
+            }
+        ]
+        eventName : Background Fetch registered
+        instanceId : my-fetch-success
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+    [1] : {
+        eventMetadata : [
+        ]
+        eventName : Background Fetch started
+        instanceId : my-fetch-success
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+    [2] : {
+        eventMetadata : [
+            [0] : {
+                key : Request Index
+                value : 0
+            }
+            [1] : {
+                key : URL
+                value : http://127.0.0.1:8000/inspector-protocol/background-services/resources/background-fetch.txt
+            }
+        ]
+        eventName : Request processing started
+        instanceId : my-fetch-success
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+    [3] : {
+        eventMetadata : [
+            [0] : {
+                key : Request Index
+                value : 0
+            }
+            [1] : {
+                key : Response Size (bytes)
+                value : 16
+            }
+            [2] : {
+                key : Response Status
+                value : 200
+            }
+            [3] : {
+                key : URL
+                value : http://127.0.0.1:8000/inspector-protocol/background-services/resources/background-fetch.txt
+            }
+        ]
+        eventName : Request processing completed
+        instanceId : my-fetch-success
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+    [4] : {
+        eventMetadata : [
+            [0] : {
+                key : Event Type
+                value : SuccessEvent
+            }
+        ]
+        eventName : Background Fetch completed
+        instanceId : my-fetch-success
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+]
+Background Fetch Failure:
+[
+    [0] : {
+        eventMetadata : [
+            [0] : {
+                key : Start Paused
+                value : No
+            }
+            [1] : {
+                key : Total Requests
+                value : 1
+            }
+        ]
+        eventName : Background Fetch registered
+        instanceId : my-fetch-failure
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+    [1] : {
+        eventMetadata : [
+        ]
+        eventName : Background Fetch started
+        instanceId : my-fetch-failure
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+    [2] : {
+        eventMetadata : [
+            [0] : {
+                key : Request Index
+                value : 0
+            }
+            [1] : {
+                key : URL
+                value : http://127.0.0.1:8000/missing/
+            }
+        ]
+        eventName : Request processing started
+        instanceId : my-fetch-failure
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+    [3] : {
+        eventMetadata : [
+            [0] : {
+                key : Request Index
+                value : 0
+            }
+            [1] : {
+                key : Response Size (bytes)
+                value : 0
+            }
+            [2] : {
+                key : Response Status
+                value : 404
+            }
+            [3] : {
+                key : URL
+                value : http://127.0.0.1:8000/missing/
+            }
+        ]
+        eventName : Request processing completed
+        instanceId : my-fetch-failure
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+    [4] : {
+        eventMetadata : [
+            [0] : {
+                key : Event Type
+                value : FailEvent
+            }
+            [1] : {
+                key : Failure Reason
+                value : BackgroundFetchFailureReason::BAD_STATUS
+            }
+        ]
+        eventName : Background Fetch completed
+        instanceId : my-fetch-failure
+        origin : http://127.0.0.1:8000/
+        service : backgroundFetch
+        timestamp : <number>
+    }
+]
+Background Sync Success:
+[
+    [0] : {
+        eventMetadata : [
+        ]
+        eventName : Registered sync
+        instanceId : background-sync-resolve
+        origin : http://127.0.0.1:8000/
+        service : backgroundSync
+        timestamp : <number>
+    }
+    [1] : {
+        eventMetadata : [
+            [0] : {
+                key : Last Chance
+                value : No
+            }
+        ]
+        eventName : Dispatched sync event
+        instanceId : background-sync-resolve
+        origin : http://127.0.0.1:8000/
+        service : backgroundSync
+        timestamp : <number>
+    }
+    [2] : {
+        eventMetadata : [
+            [0] : {
+                key : Status
+                value : succeeded
+            }
+        ]
+        eventName : Sync completed
+        instanceId : background-sync-resolve
+        origin : http://127.0.0.1:8000/
+        service : backgroundSync
+        timestamp : <number>
+    }
+]
+Background Sync Failure:
+[
+    [0] : {
+        eventMetadata : [
+        ]
+        eventName : Registered sync
+        instanceId : background-sync-reject
+        origin : http://127.0.0.1:8000/
+        service : backgroundSync
+        timestamp : <number>
+    }
+    [1] : {
+        eventMetadata : [
+            [0] : {
+                key : Last Chance
+                value : No
+            }
+        ]
+        eventName : Dispatched sync event
+        instanceId : background-sync-reject
+        origin : http://127.0.0.1:8000/
+        service : backgroundSync
+        timestamp : <number>
+    }
+    [2] : {
+        eventMetadata : [
+            [0] : {
+                key : Failure Reason
+                value : waitUntil rejected
+            }
+            [1] : {
+                key : Next Attempt Delay (ms)
+                value : 300000
+            }
+        ]
+        eventName : Sync event failed
+        instanceId : background-sync-reject
+        origin : http://127.0.0.1:8000/
+        service : backgroundSync
+        timestamp : <number>
+    }
+]
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-events.js b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-events.js
new file mode 100644
index 0000000..de23805
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-events.js
@@ -0,0 +1,66 @@
+async function setUp(dp) {
+  // Grant permission to register Background Sync events.
+  await dp.Browser.grantPermissions({
+    origin: location.origin,
+    permissions: ['backgroundSync'],
+  });
+
+  await dp.BackgroundService.startObserving({service: 'backgroundFetch'});
+  dp.BackgroundService.setRecording({shouldRecord: true, service: 'backgroundFetch'});
+  await dp.BackgroundService.onceRecordingStateChanged();
+
+  await dp.BackgroundService.startObserving({service: 'backgroundSync'});
+  dp.BackgroundService.setRecording({shouldRecord: true, service: 'backgroundSync'});
+  await dp.BackgroundService.onceRecordingStateChanged();
+}
+
+async function tearDown(dp) {
+  dp.BackgroundService.setRecording({shouldRecord: false, service: 'backgroundFetch'});
+  await dp.BackgroundService.onceRecordingStateChanged();
+  dp.BackgroundService.setRecording({shouldRecord: false, service: 'backgroundSync'});
+  await dp.BackgroundService.onceRecordingStateChanged();
+}
+
+async function waitForEvents(dp, numEvents) {
+  const events = [];
+  for (let i = 0; i < numEvents; i++)
+    events.push(await dp.BackgroundService.onceBackgroundServiceEventReceived());
+  return events.map(event => event.params.backgroundServiceEvent).map(event => {
+    // Remove the `serviceWorkerRegistrationId` property since it can change.
+    delete event.serviceWorkerRegistrationId;
+
+    // Sort the metadata.
+    event.eventMetadata = event.eventMetadata.sort(
+        (m1, m2) => JSON.stringify(m1) < JSON.stringify(m2) ? -1 : 1);
+
+    return event;
+  });
+}
+
+(async function(testRunner) {
+  var {page, session, dp} = await testRunner.startURL(
+      'resources/background-services.html',
+      `Tests that the expected events are received.`);
+
+  await session.evaluateAsync('installSW()');
+  await setUp(dp);
+
+  testRunner.log('Background Fetch Success:');
+  session.evaluate(`sw.backgroundFetch.fetch('my-fetch-success', 'background-fetch.txt')`);
+  testRunner.log(await waitForEvents(dp, 5));
+
+  testRunner.log('Background Fetch Failure:');
+  session.evaluate(`sw.backgroundFetch.fetch('my-fetch-failure', '/missing/')`);
+  testRunner.log(await waitForEvents(dp, 5));
+
+  testRunner.log('Background Sync Success:');
+  session.evaluate(`sw.sync.register('background-sync-resolve')`);
+  testRunner.log(await waitForEvents(dp, 3));
+
+  testRunner.log('Background Sync Failure:');
+  session.evaluate(`sw.sync.register('background-sync-reject')`);
+  testRunner.log(await waitForEvents(dp, 3));
+
+  await tearDown(dp);
+  testRunner.completeTest();
+});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/background-fetch.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/background-fetch.txt
new file mode 100644
index 0000000..4d54f505
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/background-fetch.txt
@@ -0,0 +1 @@
+Background Fetch
\ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/service-worker.js b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/service-worker.js
index c9870ca..6bb9973 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/service-worker.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/service-worker.js
@@ -7,3 +7,11 @@
 self.addEventListener(
     'backgroundfetchsuccess',
     event => postMessageToWindow(`Completed "${event.registration.id}"`));
+
+self.addEventListener(
+    'backgroundfetchfail',
+    event => postMessageToWindow(`Completed "${event.registration.id}"`));
+
+self.addEventListener(
+    'sync',
+    event => event.waitUntil(event.tag === 'background-sync-resolve' ? Promise.resolve() : Promise.reject()));
diff --git a/third_party/blink/web_tests/http/tests/navigation/javascriptlink-frames-expected.txt b/third_party/blink/web_tests/http/tests/navigation/javascriptlink-frames-expected.txt
index 77d8b56..9178720 100644
--- a/third_party/blink/web_tests/http/tests/navigation/javascriptlink-frames-expected.txt
+++ b/third_party/blink/web_tests/http/tests/navigation/javascriptlink-frames-expected.txt
@@ -2,6 +2,9 @@
 
 ============== Back Forward List ==============
         http://127.0.0.1:8000/navigation/javascriptlink-frames.html
+        http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=javascriptlink.html
+            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
+            http://127.0.0.1:8000/navigation/resources/javascriptlink.html (in frame "main")
 curr->  http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=javascriptlink.html
             http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
             http://127.0.0.1:8000/navigation/resources/success200.html (in frame "main")
diff --git a/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.html b/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.html
new file mode 100644
index 0000000..5e72a42
--- /dev/null
+++ b/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<svg id="svg" style="width: 100px">
+  <rect width="100" height="100" stroke="blue" stroke-width="25">
+</svg>
diff --git a/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.txt b/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.txt
new file mode 100644
index 0000000..07c4a85
--- /dev/null
+++ b/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke-expected.txt
@@ -0,0 +1,34 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "LayoutSVGRoot svg id='svg'",
+          "rect": [7, 7, 102, 115],
+          "reason": "paint property change"
+        },
+        {
+          "object": "LayoutSVGRoot svg id='svg'",
+          "rect": [7, 7, 3, 115],
+          "reason": "paint property change"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke.html b/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke.html
new file mode 100644
index 0000000..21ee781e
--- /dev/null
+++ b/third_party/blink/web_tests/paint/invalidation/svg/resize-svg-root-with-child-stroke.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script src="../resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  svg.style.width = '100px';
+}
+onload = runRepaintAndPixelTest;
+</script>
+<svg id="svg" style="width: 1px">
+  <rect width="100" height="100" stroke="blue" stroke-width="25">
+</svg>
diff --git a/third_party/blink/web_tests/platform/mac/http/tests/devtools/elements/styles-2/force-pseudo-state-expected.txt b/third_party/blink/web_tests/platform/mac/http/tests/devtools/elements/styles-2/force-pseudo-state-expected.txt
new file mode 100644
index 0000000..9477dd0
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/http/tests/devtools/elements/styles-2/force-pseudo-state-expected.txt
@@ -0,0 +1,118 @@
+Tests that forced element state is reflected in the DOM tree and Styles pane.
+
+
+DIV with :hover and :active
+[expanded] 
+element.style { ()
+
+[expanded] 
+div:active, a:active { (<style>)
+    font-weight: bold;
+
+[expanded] 
+div:hover, a:hover { (<style>)
+    color: red;
+
+[expanded] 
+div { (user agent stylesheet)
+    display: block;
+
+======== Inherited from body#mainBody.main1.main2.mainpage ========
+[expanded] 
+Style Attribute { ()
+/-- overloaded --/     font-weight: normal;
+
+======== Inherited from html ========
+[expanded] 
+html { (user agent stylesheet)
+/-- overloaded --/     color: -internal-root-color;
+
+- <html> [subtreeMarkerCount:1]
+    + <head>…</head>
+    - <body id="mainBody" class="main1 main2 mainpage" style="font-weight: normal; width: 85%; background-image: url(bar.png)"> [subtreeMarkerCount:1]
+          <div id="div">Test text</div> [markers:[pseudo-state-marker=hover,active], subtreeMarkerCount:1]
+      </body>
+  </html>
+
+DIV with :active and :focus
+[expanded] 
+element.style { ()
+
+[expanded] 
+div:active, a:active { (<style>)
+    font-weight: bold;
+
+[expanded] 
+div:focus, a:focus { (<style>)
+    border: 1px solid green;
+        border-top-color: green;
+        border-top-style: solid;
+        border-top-width: 1px;
+        border-right-color: green;
+        border-right-style: solid;
+        border-right-width: 1px;
+        border-bottom-color: green;
+        border-bottom-style: solid;
+        border-bottom-width: 1px;
+        border-left-color: green;
+        border-left-style: solid;
+        border-left-width: 1px;
+        border-image-source: initial;
+        border-image-slice: initial;
+        border-image-width: initial;
+        border-image-outset: initial;
+        border-image-repeat: initial;
+
+[expanded] 
+:focus { (user agent stylesheet)
+    outline: -webkit-focus-ring-color auto 5px;
+        outline-color: -webkit-focus-ring-color;
+        outline-style: auto;
+        outline-width: 5px;
+
+[expanded] 
+div { (user agent stylesheet)
+    display: block;
+
+======== Inherited from body#mainBody.main1.main2.mainpage ========
+[expanded] 
+Style Attribute { ()
+/-- overloaded --/     font-weight: normal;
+
+======== Inherited from html ========
+[expanded] 
+html { (user agent stylesheet)
+    color: -internal-root-color;
+
+- <html> [subtreeMarkerCount:1]
+    + <head>…</head>
+    - <body id="mainBody" class="main1 main2 mainpage" style="font-weight: normal; width: 85%; background-image: url(bar.png)"> [subtreeMarkerCount:1]
+          <div id="div">Test text</div> [markers:[pseudo-state-marker=active,focus], subtreeMarkerCount:1]
+      </body>
+  </html>
+
+DIV with no forced state
+[expanded] 
+element.style { ()
+
+[expanded] 
+div { (user agent stylesheet)
+    display: block;
+
+======== Inherited from body#mainBody.main1.main2.mainpage ========
+[expanded] 
+Style Attribute { ()
+    font-weight: normal;
+
+======== Inherited from html ========
+[expanded] 
+html { (user agent stylesheet)
+    color: -internal-root-color;
+
+- <html>
+    + <head>…</head>
+    - <body id="mainBody" class="main1 main2 mainpage" style="font-weight: normal; width: 85%; background-image: url(bar.png)">
+          <div id="div">Test text</div>
+      </body>
+  </html>
+
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
index ba2fc0a8..27f46ee4 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
@@ -23,34 +23,14 @@
           "reason": "geometry"
         },
         {
-          "object": "LayoutSVGEllipse circle",
+          "object": "LayoutSVGRoot svg",
           "rect": [47, 107, 324, 324],
-          "reason": "SVG resource change"
+          "reason": "paint property change"
         },
         {
           "object": "LayoutSVGRoot svg",
-          "rect": [47, 388, 324, 43],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [47, 107, 324, 43],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [110, 150, 261, 238],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGEllipse circle",
-          "rect": [8, 150, 170, 238],
-          "reason": "SVG resource change"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [8, 150, 39, 238],
-          "reason": "incremental"
+          "rect": [8, 150, 102, 238],
+          "reason": "paint property change"
         }
       ]
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
index 294fe0e2..48ce931 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
@@ -23,34 +23,14 @@
           "reason": "geometry"
         },
         {
-          "object": "LayoutSVGEllipse circle",
+          "object": "LayoutSVGRoot svg",
           "rect": [47, 111, 324, 324],
-          "reason": "SVG resource change"
+          "reason": "paint property change"
         },
         {
           "object": "LayoutSVGRoot svg",
-          "rect": [47, 392, 324, 43],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [47, 111, 324, 43],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [110, 154, 261, 238],
-          "reason": "incremental"
-        },
-        {
-          "object": "LayoutSVGEllipse circle",
-          "rect": [8, 154, 170, 238],
-          "reason": "SVG resource change"
-        },
-        {
-          "object": "LayoutSVGRoot svg",
-          "rect": [8, 154, 39, 238],
-          "reason": "incremental"
+          "rect": [8, 154, 102, 238],
+          "reason": "paint property change"
         }
       ]
     }
diff --git a/third_party/blink/web_tests/virtual/display-lock/display-lock/README.txt b/third_party/blink/web_tests/virtual/display-lock/display-lock/README.txt
deleted file mode 100644
index 1704d2b..0000000
--- a/third_party/blink/web_tests/virtual/display-lock/display-lock/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This tests a display locking feature. It runs tests until display-lock directory
-with --enable-blink-features=DisplayLocking flag.
diff --git a/third_party/blink/web_tests/virtual/display-lock/wpt_internal/display-lock/README.txt b/third_party/blink/web_tests/virtual/display-lock/wpt_internal/display-lock/README.txt
new file mode 100644
index 0000000..3ab915dd
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/display-lock/wpt_internal/display-lock/README.txt
@@ -0,0 +1,2 @@
+This tests a display locking feature. It runs tests in wpt_internal/display-lock
+directory with --enable-blink-features=DisplayLocking flag.
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/README.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/README.txt
deleted file mode 100644
index f6531942..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-This suite runs all media tests with UseSurfaceLayerForVideo feature enabled.
-It also uses --enable-display-compositor-pixel-dump in order to properly render
-tests using SurfaceLayer.
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplay-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplay-expected.txt
deleted file mode 100644
index 5e6fde0..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplay-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger canplay event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplay_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplay_manual-expected.txt
deleted file mode 100644
index 9a159c4d..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplay_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger canplay event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplaythrough-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplaythrough-expected.txt
deleted file mode 100644
index cac961ab..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplaythrough-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger canplaythrough event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplaythrough_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplaythrough_manual-expected.txt
deleted file mode 100644
index 24a8ab4..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_canplaythrough_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger canplaythrough event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadeddata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadeddata-expected.txt
deleted file mode 100644
index 1a24cbb..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadeddata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadeddata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadeddata_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadeddata_manual-expected.txt
deleted file mode 100644
index 102dc02..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadeddata_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger loadeddata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadedmetadata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadedmetadata-expected.txt
deleted file mode 100644
index 114c8ec..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadedmetadata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadedmetadata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadedmetadata_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadedmetadata_manual-expected.txt
deleted file mode 100644
index 004d77d..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadedmetadata_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger loadedmetadata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadstart-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadstart-expected.txt
deleted file mode 100644
index ac4658bc..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadstart-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadstart event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadstart_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadstart_manual-expected.txt
deleted file mode 100644
index f98b9e3b..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_loadstart_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger loadstart event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_canplay_canplaythrough-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_canplay_canplaythrough-expected.txt
deleted file mode 100644
index b3d596c2..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_canplay_canplaythrough-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger canplay then canplaythrough event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_canplay_playing-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_canplay_playing-expected.txt
deleted file mode 100644
index 26450c7..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_canplay_playing-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger canplay then playing event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_loadedmetadata_loadeddata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_loadedmetadata_loadeddata-expected.txt
deleted file mode 100644
index 465e9aa5..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_loadedmetadata_loadeddata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadedmetadata then loadeddata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_loadstart_progress-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_loadstart_progress-expected.txt
deleted file mode 100644
index 708552a..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_order_loadstart_progress-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadstart then progress event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_pause_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_pause_manual-expected.txt
deleted file mode 100644
index d0d06558..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_pause_manual-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
-calling play() then pause() on non-autoplay video should trigger pause event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_play-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_play-expected.txt
deleted file mode 100644
index ea471f8..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_play-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger play event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_play_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_play_manual-expected.txt
deleted file mode 100644
index 02ef9a5..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_play_manual-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
-calling play() on video should trigger play event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_playing-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_playing-expected.txt
deleted file mode 100644
index a4021332..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_playing-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger playing event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_playing_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_playing_manual-expected.txt
deleted file mode 100644
index e931338..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_playing_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-calling play() on video should trigger playing event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_progress-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_progress-expected.txt
deleted file mode 100644
index 79e6d69..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_progress-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger progress event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_progress_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_progress_manual-expected.txt
deleted file mode 100644
index 690a093..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_progress_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger progress event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_timeupdate-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_timeupdate-expected.txt
deleted file mode 100644
index 8257ee3..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_timeupdate-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on a sufficiently long autoplay video should trigger timeupdate event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_timeupdate_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_timeupdate_manual-expected.txt
deleted file mode 100644
index e0e7b28..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/events/event_timeupdate_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-calling play() on a sufficiently long video should trigger timeupdate event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/networkState/networkState_during_loadstart-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/networkState/networkState_during_loadstart-expected.txt
deleted file mode 100644
index ee38b43..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/networkState/networkState_during_loadstart-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-audioElement.networkState should be NETWORK_LOADING during loadstart event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "2" is "2"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/paused/paused_false_during_play-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/paused/paused_false_during_play-expected.txt
deleted file mode 100644
index e7288c2..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/paused/paused_false_during_play-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-audio.paused should be false during play event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS false is false
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/paused/paused_true_during_pause-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/paused/paused_true_during_pause-expected.txt
deleted file mode 100644
index e52c8cb..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/paused/paused_true_during_pause-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
-audio.paused should be true during pause event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_canplay-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_canplay-expected.txt
deleted file mode 100644
index b396331..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_canplay-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-audio.readyState should be >= HAVE_FUTURE_DATA during canplay event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_canplaythrough-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_canplaythrough-expected.txt
deleted file mode 100644
index 2357f59..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_canplaythrough-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-audio.readyState should be HAVE_ENOUGH_DATA during canplaythrough event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "4" is "4"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_loadeddata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_loadeddata-expected.txt
deleted file mode 100644
index 3b98ef2..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_loadeddata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-audio.readyState should be >= HAVE_CURRENT_DATA during loadeddata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_loadedmetadata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_loadedmetadata-expected.txt
deleted file mode 100644
index dd16c3f..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_loadedmetadata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-audio.readyState should be >= HAVE_METADATA during loadedmetadata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_playing-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_playing-expected.txt
deleted file mode 100644
index 210bfa0..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/audio/readyState/readyState_during_playing-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-audio.readyState should be >= HAVE_FUTURE_DATA during playing event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_empty_if_no_src-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_empty_if_no_src-expected.txt
deleted file mode 100644
index 15fa14a..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_empty_if_no_src-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.currentSrc - empty if no source
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "" is ""
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_nonempty_after_adding_source_child-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_nonempty_after_adding_source_child-expected.txt
deleted file mode 100644
index 2723776..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_nonempty_after_adding_source_child-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-videoElement.currentSrc should not be empty after adding source element (even with a bogus value)
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS false is false
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_property_exists-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_property_exists-expected.txt
deleted file mode 100644
index aabc979..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/currentSrc/currentSrc_property_exists-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.currentSrc - existence test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_null-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_null-expected.txt
deleted file mode 100644
index cc1125e8..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_null-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.error - null if no source
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "null" is "null"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_onerror_called_on_bogus_source-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_onerror_called_on_bogus_source-expected.txt
deleted file mode 100644
index af769cc..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_onerror_called_on_bogus_source-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-videoElement.onerror is triggered on bogus source
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "4" is "4"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_property_exists-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_property_exists-expected.txt
deleted file mode 100644
index 55cf1ff..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/error/error_property_exists-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.error - existence test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplay-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplay-expected.txt
deleted file mode 100644
index 5e6fde0..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplay-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger canplay event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplay_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplay_manual-expected.txt
deleted file mode 100644
index 9a159c4d..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplay_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger canplay event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplaythrough-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplaythrough-expected.txt
deleted file mode 100644
index cac961ab..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplaythrough-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger canplaythrough event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplaythrough_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplaythrough_manual-expected.txt
deleted file mode 100644
index 24a8ab4..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_canplaythrough_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger canplaythrough event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadeddata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadeddata-expected.txt
deleted file mode 100644
index 1a24cbb..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadeddata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadeddata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadeddata_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadeddata_manual-expected.txt
deleted file mode 100644
index 102dc02..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadeddata_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger loadeddata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadedmetadata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadedmetadata-expected.txt
deleted file mode 100644
index 114c8ec..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadedmetadata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadedmetadata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadedmetadata_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadedmetadata_manual-expected.txt
deleted file mode 100644
index 004d77d..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadedmetadata_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger loadedmetadata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadstart-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadstart-expected.txt
deleted file mode 100644
index ac4658bc..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadstart-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadstart event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadstart_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadstart_manual-expected.txt
deleted file mode 100644
index f98b9e3b..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_loadstart_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger loadstart event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_canplay_canplaythrough-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_canplay_canplaythrough-expected.txt
deleted file mode 100644
index b3d596c2..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_canplay_canplaythrough-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger canplay then canplaythrough event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_canplay_playing-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_canplay_playing-expected.txt
deleted file mode 100644
index 26450c7..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_canplay_playing-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger canplay then playing event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_loadedmetadata_loadeddata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_loadedmetadata_loadeddata-expected.txt
deleted file mode 100644
index 465e9aa5..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_loadedmetadata_loadeddata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadedmetadata then loadeddata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_loadstart_progress-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_loadstart_progress-expected.txt
deleted file mode 100644
index 708552a..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_order_loadstart_progress-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger loadstart then progress event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_pause_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_pause_manual-expected.txt
deleted file mode 100644
index d0d06558..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_pause_manual-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
-calling play() then pause() on non-autoplay video should trigger pause event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_play-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_play-expected.txt
deleted file mode 100644
index ea471f8..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_play-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger play event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_play_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_play_manual-expected.txt
deleted file mode 100644
index 02ef9a5..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_play_manual-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
-calling play() on video should trigger play event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_playing-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_playing-expected.txt
deleted file mode 100644
index a4021332..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_playing-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger playing event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_playing_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_playing_manual-expected.txt
deleted file mode 100644
index e931338..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_playing_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-calling play() on video should trigger playing event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_progress-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_progress-expected.txt
deleted file mode 100644
index 79e6d69..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_progress-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on autoplay video should trigger progress event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_progress_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_progress_manual-expected.txt
deleted file mode 100644
index 690a093..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_progress_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on non-autoplay video should trigger progress event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_timeupdate-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_timeupdate-expected.txt
deleted file mode 100644
index 8257ee3..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_timeupdate-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setting src attribute on a sufficiently long autoplay video should trigger timeupdate event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_timeupdate_manual-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_timeupdate_manual-expected.txt
deleted file mode 100644
index e0e7b28..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/events/event_timeupdate_manual-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-calling play() on a sufficiently long video should trigger timeupdate event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_during_loadstart-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_during_loadstart-expected.txt
deleted file mode 100644
index 21b1a84..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_during_loadstart-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-videoElement.networkState should be NETWORK_LOADING during loadstart event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "2" is "2"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_initial-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_initial-expected.txt
deleted file mode 100644
index 1c86bf7..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_initial-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.networkState - default state
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "0" is "0"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_property_exists-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_property_exists-expected.txt
deleted file mode 100644
index 586a8b44..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/networkState/networkState_property_exists-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.networkState - existence test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/paused/paused_false_during_play-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/paused/paused_false_during_play-expected.txt
deleted file mode 100644
index 2f42a05..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/paused/paused_false_during_play-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.paused should be false during play event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS false is false
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/paused/paused_true_during_pause-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/paused/paused_true_during_pause-expected.txt
deleted file mode 100644
index d82edd2..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/paused/paused_true_during_pause-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
-video.paused should be true during pause event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_property_exists-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_property_exists-expected.txt
deleted file mode 100644
index 20bf8d21..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_property_exists-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.preload - existence test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_auto_value-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_auto_value-expected.txt
deleted file mode 100644
index 5ebd452..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_auto_value-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.preload - reflection test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "auto" is "auto"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_bogus_value-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_bogus_value-expected.txt
deleted file mode 100644
index 0cb5b25..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_bogus_value-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.preload - reflection test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "metadata" is "metadata"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_empty-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_empty-expected.txt
deleted file mode 100644
index 5ebd452..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_empty-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.preload - reflection test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "auto" is "auto"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_metadata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_metadata-expected.txt
deleted file mode 100644
index 0cb5b25..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_metadata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.preload - reflection test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "metadata" is "metadata"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_no_value-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_no_value-expected.txt
deleted file mode 100644
index 0cb5b25..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_no_value-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.preload - reflection test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "metadata" is "metadata"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_none-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_none-expected.txt
deleted file mode 100644
index 0570dfa..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_none-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.preload - reflection test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "none" is "none"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_none_autoplay-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_none_autoplay-expected.txt
deleted file mode 100644
index 0570dfa..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/preload/preload_reflects_none_autoplay-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.preload - reflection test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "none" is "none"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_canplay-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_canplay-expected.txt
deleted file mode 100644
index e2fa4c5..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_canplay-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.readyState should be >= HAVE_FUTURE_DATA during canplay event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_canplaythrough-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_canplaythrough-expected.txt
deleted file mode 100644
index 948bf98..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_canplaythrough-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.readyState should be HAVE_ENOUGH_DATA during canplaythrough event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "4" is "4"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_loadeddata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_loadeddata-expected.txt
deleted file mode 100644
index 3c10903..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_loadeddata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.readyState should be >= HAVE_CURRENT_DATA during loadeddata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_loadedmetadata-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_loadedmetadata-expected.txt
deleted file mode 100644
index 202c0a41..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_loadedmetadata-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.readyState should be >= HAVE_METADATA during loadedmetadata event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_playing-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_playing-expected.txt
deleted file mode 100644
index d70c1f29..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_during_playing-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.readyState should be >= HAVE_FUTURE_DATA during playing event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_initial-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_initial-expected.txt
deleted file mode 100644
index b9f65069..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_initial-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.readyState - default state
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "0" is "0"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_property_exists-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_property_exists-expected.txt
deleted file mode 100644
index c1d4a16..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/readyState/readyState_property_exists-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.readyState - existence test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_reflects_attribute_not_source_elements-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_reflects_attribute_not_source_elements-expected.txt
deleted file mode 100644
index 1ce3015..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_reflects_attribute_not_source_elements-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.src - reflection test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_reflects_no_value-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_reflects_no_value-expected.txt
deleted file mode 100644
index 123ee9a..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_reflects_no_value-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-video.src - empty if no source
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS "" is ""
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_removal_does_not_trigger_loadstart-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_removal_does_not_trigger_loadstart-expected.txt
deleted file mode 100644
index 30c28eb..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/W3C/video/src/src_removal_does_not_trigger_loadstart-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-removing src attribute should not trigger loadstart event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS true is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-spec reference
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/fallback-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/fallback-expected.txt
deleted file mode 100644
index 9d8b3f4..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/fallback-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test that fallback content is not rendered
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/media-document-audio-size-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/media-document-audio-size-expected.txt
deleted file mode 100644
index cb02db2..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/media-document-audio-size-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This tests that in a standalone media document with audio content, the media element has non-zero size.
-
-PASS
-
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/svg-as-image-with-media-blocked-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/svg-as-image-with-media-blocked-expected.txt
deleted file mode 100644
index df1c1b6a..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/svg-as-image-with-media-blocked-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-This test attempts to load foreignObject audio and video embedded in an SVG file loaded as the src attribute of an img element. If successful, none of these files will load and a green rectangle will be visible below this text. If unsuccessful, the browser will crash while attempting to load the media.
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/track/media-element-move-to-new-document-assert-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/track/media-element-move-to-new-document-assert-expected.txt
deleted file mode 100644
index 55232518..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/track/media-element-move-to-new-document-assert-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test for failing EventDispatchForbiddenScope assert when moving a video with text track between documents.
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/video-canvas-alpha-expected.png b/third_party/blink/web_tests/virtual/video-surface-layer/media/video-canvas-alpha-expected.png
deleted file mode 100644
index c21d7235..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/video-canvas-alpha-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/video-plays-past-end-of-test-expected.txt b/third_party/blink/web_tests/virtual/video-surface-layer/media/video-plays-past-end-of-test-expected.txt
deleted file mode 100644
index c4d9535..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/video-plays-past-end-of-test-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-This test intentionally lets the video keep playing past end of test to ensure that shutdown is clean, since DumpRenderTree used to crash in this case.
diff --git a/third_party/blink/web_tests/virtual/video-surface-layer/media/video-transformed-expected.png b/third_party/blink/web_tests/virtual/video-surface-layer/media/video-transformed-expected.png
deleted file mode 100644
index cbc3b756..0000000
--- a/third_party/blink/web_tests/virtual/video-surface-layer/media/video-transformed-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/ice-state.https-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/ice-state.https-expected.txt
new file mode 100644
index 0000000..61df94a8
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/ice-state.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS PC should enter connected state when candidates are sent
+PASS PC should generate offer with a=ice-options:trickle
+FAIL PC should enter disconnected state when a failing candidate is sent promise_test: Unhandled rejection with value: "Unexpected state encountered: failed"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
index fdced4c..f53002f0 100644
--- a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
@@ -879,6 +879,8 @@
 html element plaintext
 html element portal
     property activate
+    property onmessage
+    property onmessageerror
     property postMessage
     property src
 html element pre
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 0609c9f..ea8ef1e 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -3625,10 +3625,14 @@
     method constructor
 interface HTMLPortalElement : HTMLElement
     attribute @@toStringTag
+    getter onmessage
+    getter onmessageerror
     getter src
     method activate
     method constructor
     method postMessage
+    setter onmessage
+    setter onmessageerror
     setter src
 interface HTMLPreElement : HTMLElement
     attribute @@toStringTag
@@ -5564,8 +5568,12 @@
     method constructor
 interface PortalHost : EventTarget
     attribute @@toStringTag
+    getter onmessage
+    getter onmessageerror
     method constructor
     method postMessage
+    setter onmessage
+    setter onmessageerror
 interface Presentation
     attribute @@toStringTag
     getter defaultRequest
diff --git a/third_party/blink/web_tests/display-lock/activation/activate-commit-same-frame.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-commit-same-frame.html
similarity index 74%
rename from third_party/blink/web_tests/display-lock/activation/activate-commit-same-frame.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-commit-same-frame.html
index 511c530..4705208 100644
--- a/third_party/blink/web_tests/display-lock/activation/activate-commit-same-frame.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-commit-same-frame.html
@@ -1,7 +1,12 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: activate commit same frame</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <style>
 .spacer {
@@ -47,3 +52,4 @@
 }, "scrollIntoView and committing on the same frame should work");
 
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/activate-update-and-commit-same-frame.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-update-and-commit-same-frame.html
similarity index 75%
rename from third_party/blink/web_tests/display-lock/activation/activate-update-and-commit-same-frame.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-update-and-commit-same-frame.html
index 85411cf..df12bd4 100644
--- a/third_party/blink/web_tests/display-lock/activation/activate-update-and-commit-same-frame.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-update-and-commit-same-frame.html
@@ -1,7 +1,12 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: activate update+commit same frame</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <style>
 .spacer {
@@ -46,4 +51,4 @@
 }, "scrollIntoView and calling updateAndCommit on the same frame should work");
 
 </script>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/activate-update-same-frame.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-update-same-frame.html
similarity index 74%
rename from third_party/blink/web_tests/display-lock/activation/activate-update-same-frame.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-update-same-frame.html
index 325067f13..4c37cb7 100644
--- a/third_party/blink/web_tests/display-lock/activation/activate-update-same-frame.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/activate-update-same-frame.html
@@ -1,7 +1,12 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: activate update same frame</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <style>
 .spacer {
@@ -46,3 +51,4 @@
 }, "scrollIntoView and updating on the same frame should work");
 
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/anchor-links-ancestor.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/anchor-links-ancestor.html
similarity index 86%
rename from third_party/blink/web_tests/display-lock/activation/anchor-links-ancestor.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/anchor-links-ancestor.html
index a11de7cc..962e9c3a 100644
--- a/third_party/blink/web_tests/display-lock/activation/anchor-links-ancestor.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/anchor-links-ancestor.html
@@ -1,7 +1,12 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: anchor links via click</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <style>
   div {
     contain: style layout;
@@ -74,3 +79,4 @@
   });
 }, "Activation through anchor link fires beforeactivate on locked ancestor");
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/anchor-links.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/anchor-links.html
similarity index 74%
rename from third_party/blink/web_tests/display-lock/activation/anchor-links.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/anchor-links.html
index 52f4f071..99dab79 100644
--- a/third_party/blink/web_tests/display-lock/activation/anchor-links.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/anchor-links.html
@@ -1,7 +1,12 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: anchor links</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <style>
   div {
     contain: style layout;
@@ -39,3 +44,4 @@
   });
 }, "Activation through anchor link fires beforeactivate on locked element");
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/focus-empty-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-empty-layout.html
similarity index 74%
rename from third_party/blink/web_tests/display-lock/activation/focus-empty-layout.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-empty-layout.html
index 3154573..2a1e0b4 100644
--- a/third_party/blink/web_tests/display-lock/activation/focus-empty-layout.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-empty-layout.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: focus on new element</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <!--
 Focus on a div that doesn't have style/layout value yet.
@@ -7,8 +12,8 @@
 <div id="container" style ="contain:style layout">
 </div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 promise_test((t) => {
@@ -36,3 +41,4 @@
   });
 }, "Activating locked element through tabindex navigation fires beforeactivate, focuses element");
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/focus-shadow.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-shadow.html
similarity index 78%
rename from third_party/blink/web_tests/display-lock/activation/focus-shadow.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-shadow.html
index e313591..e4534906 100644
--- a/third_party/blink/web_tests/display-lock/activation/focus-shadow.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-shadow.html
@@ -1,11 +1,16 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: focus shadow</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <div id="host">
   <input id="slotted" type="text">
 </div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 promise_test((t) => {
@@ -40,3 +45,4 @@
   });
 }, "Activating locked element through focus() fires beforeactivate, doesn't go through shadow boundary");
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/focus-updated-style.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-updated-style.html
similarity index 67%
rename from third_party/blink/web_tests/display-lock/activation/focus-updated-style.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-updated-style.html
index 2a8c0a7..6964e7bb 100644
--- a/third_party/blink/web_tests/display-lock/activation/focus-updated-style.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/focus-updated-style.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: focus on styled element</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <!--
 Focus on a div that has updated style/layout.
@@ -10,8 +15,8 @@
   </div>
 </div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 promise_test((t) => {
@@ -27,3 +32,4 @@
   });
 }, "Trying to focus on an element in a locked subtree that's not visible anymore won't work");
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/focus.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/focus.html
similarity index 71%
rename from third_party/blink/web_tests/display-lock/activation/focus.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/focus.html
index 72832558..2389d44 100644
--- a/third_party/blink/web_tests/display-lock/activation/focus.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/focus.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: focus via tab navigation</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <div id="container" style ="contain:style layout">
   <div id="focusable" tabIndex="0">
@@ -6,8 +11,8 @@
   </div>
 </div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 promise_test(() => {
@@ -31,3 +36,4 @@
   });
 }, "Activating locked element through tabindex navigation fires beforeactivate, focuses element");
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/activation/scroll-into-view-beforeactivate.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view-beforeactivate.html
similarity index 85%
rename from third_party/blink/web_tests/display-lock/activation/scroll-into-view-beforeactivate.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view-beforeactivate.html
index c410eeaa..c5aa628 100644
--- a/third_party/blink/web_tests/display-lock/activation/scroll-into-view-beforeactivate.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view-beforeactivate.html
@@ -1,7 +1,12 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: scrollIntoView event</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <style>
   div {
     contain: style layout;
@@ -73,3 +78,4 @@
   });
 }, "Activation through scrollIntoView fires beforeactivate on locked ancestor");
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view-ref.html
new file mode 100644
index 0000000..ce0e0b6
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view-ref.html
@@ -0,0 +1,39 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: scrollIntoView (reference)</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+.spacer {
+  width: 150px;
+  height: 3000px;
+  background: lightblue;
+}
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightgreen;
+}
+#target {
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+
+<div class="spacer"></div>
+<div id="container"><div id="target"></div></div>
+
+<script>
+function runTest() {
+  document.getElementById("target").scrollIntoView();
+  requestAnimationFrame(takeScreenshot);
+}
+
+window.onload = () => { requestAnimationFrame(runTest); };
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view.html b/third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view.html
new file mode 100644
index 0000000..5882138
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/activation/scroll-into-view.html
@@ -0,0 +1,43 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: scrollIntoView</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="scroll-into-view-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+.spacer {
+  width: 150px;
+  height: 3000px;
+  background: lightblue;
+}
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightgreen;
+}
+#target {
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+
+<div class="spacer"></div>
+<div id="container"><div id="target"></div></div>
+
+<script>
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity, activatable: true }).then(() => {
+    document.getElementById("target").scrollIntoView();
+    requestAnimationFrame(takeScreenshot);
+  });
+}
+
+window.onload = () => { requestAnimationFrame(runTest); };
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-after-resize-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-after-resize-ref.html
new file mode 100644
index 0000000..977d9fd
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-after-resize-ref.html
@@ -0,0 +1,24 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire after resizing (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+}
+#spacer {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="container"></div>
+<div id="spacer"></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-after-resize.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-after-resize.html
new file mode 100644
index 0000000..ad22fa0
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-after-resize.html
@@ -0,0 +1,42 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire after resizing</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-after-resize-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+.contained {
+  contain: style layout;
+  background: lightblue;
+}
+#spacer {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+<div id="small" class="contained"></div>
+<div id="spacer">
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("small");
+  container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(
+    () => { finishTest("PASS"); },
+    (e) => { finishTest("FAIL " + e.message); });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-changed-containment.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-changed-containment.html
new file mode 100644
index 0000000..76474bd
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-changed-containment.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, containment changes</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-no-containment-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log"></div>
+<div id="container" style="contain: style layout;"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("container");
+  container.style = "";
+  container.displayLock.acquire({ timeout: Infinity }).then(
+    () => { finishTest("FAIL"); },
+    (e) => { finishTest("PASS " + e.message); });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-commit.html
similarity index 60%
rename from third_party/blink/web_tests/display-lock/lock-after-append/acquire-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-commit.html
index 60aebdaa..564c452 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-commit.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, appends a child, and calls commit.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -22,21 +25,16 @@
 <div id="container"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.getElementById("container");
+  const container = document.getElementById("container");
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.id = "child";
     container.appendChild(child);
 
@@ -48,3 +46,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-immediate-commit-resolves.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-immediate-commit-resolves.html
new file mode 100644
index 0000000..ca88b181
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-immediate-commit-resolves.html
@@ -0,0 +1,49 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, immediate commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+<div id="container"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity });
+
+  const child = document.createElement("div");
+  child.id = "child";
+  container.appendChild(child);
+
+  container.displayLock.commit().then(
+    () => { finishTest("PASS"); },
+    (e) => { finishTest("FAIL " + e.message); });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-immediate-update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-immediate-update-and-commit.html
new file mode 100644
index 0000000..08f175b
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-immediate-update-and-commit.html
@@ -0,0 +1,49 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, immediate updateAndCommit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+<div id="container"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity });
+
+  const child = document.createElement("div");
+  child.id = "child";
+  container.appendChild(child);
+
+  container.displayLock.updateAndCommit().then(
+    () => { finishTest("PASS"); },
+    (e) => { finishTest("FAIL " + e.message); });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-in-iframe-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-in-iframe-ref.html
new file mode 100644
index 0000000..5cdb63b1
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-in-iframe-ref.html
@@ -0,0 +1,10 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire in iframe (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<div id="log">PASS</div>
+<iframe></iframe>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-in-iframe.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-in-iframe.html
new file mode 100644
index 0000000..ed07264
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-in-iframe.html
@@ -0,0 +1,39 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire in iframe</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-in-iframe-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<div id="log"></div>
+<iframe id="frame" srcdoc='
+  <style>
+  #container {
+    contain: style layout;
+    width: 100px;
+    height: 100px;
+    background: lightblue;
+  }
+  </style>
+  <div id="container"></div>
+'></iframe>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("frame").contentDocument.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity }).then(
+    () => { finishTest("PASS"); },
+    (e) => { finishTest("FAIL " + e.message); });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-added-containment-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-added-containment-ref.html
new file mode 100644
index 0000000..1802299
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-added-containment-ref.html
@@ -0,0 +1,17 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire on added containment (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  width: 150px;
+  height: 150px;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="container"></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-added-containment.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-added-containment.html
new file mode 100644
index 0000000..c70cbf27
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-added-containment.html
@@ -0,0 +1,46 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire after added containment</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-on-added-containment-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+.contained {
+  contain: style layout;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+<div id="container"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("container");
+  container.classList = "contained";
+  container.displayLock.acquire({ timeout: Infinity }).then(
+    () => { finishTest("PASS"); },
+    (e) => { finishTest("FAIL " + e.message); });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-composited-layer.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-composited-layer.html
new file mode 100644
index 0000000..0b47a24
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-composited-layer.html
@@ -0,0 +1,40 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire on composited layer</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  will-change: transform;
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log"></div>
+<div id="container"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity }).then(
+    () => { finishTest("PASS"); },
+    (e) => { finishTest("FAIL " + e.message); }
+  );
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-no-containment.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-no-containment.html
new file mode 100644
index 0000000..52711d3
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-on-no-containment.html
@@ -0,0 +1,37 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, no containment</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-no-containment-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log"></div>
+<div id="container"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity }).then(
+    () => { finishTest("FAIL"); },
+    (e) => { finishTest("PASS " + e.message); });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-rejects-after-immediate-commit-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-rejects-after-immediate-commit-ref.html
new file mode 100644
index 0000000..9a6718ef
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-rejects-after-immediate-commit-ref.html
@@ -0,0 +1,24 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire rejects after quick commit (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log">PASS Lock commit was requested.</div>
+<div id="container"><div id="child"></div></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-rejects-after-immediate-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-rejects-after-immediate-commit.html
new file mode 100644
index 0000000..0df6921
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-rejects-after-immediate-commit.html
@@ -0,0 +1,49 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire rejects after quick commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-rejects-after-immediate-commit-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+<div id="container"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity }).then(
+    () => { finishTest("FAIL"); },
+    (e) => { finishTest("PASS " + e.message); });
+
+  const child = document.createElement("div");
+  child.id = "child";
+  container.appendChild(child);
+
+  container.displayLock.commit();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-update-disconnect-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-update-disconnect-commit.html
similarity index 62%
rename from third_party/blink/web_tests/display-lock/lock-after-append/acquire-update-disconnect-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-update-disconnect-commit.html
index 65accc7..fa774cb84 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-update-disconnect-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/acquire-update-disconnect-commit.html
@@ -1,4 +1,11 @@
 <!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, update, disconnect, commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -18,24 +25,19 @@
 <div id="container"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.getElementById("container");
+  const container = document.getElementById("container");
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
     // Update, then disconnect the element, and commit.
-    let update_promise = container.displayLock.update();
+    const update_promise = container.displayLock.update();
     container.remove();
-    let commit_promise = container.displayLock.commit();
+    const commit_promise = container.displayLock.commit();
 
     // The update promise should reject and commit one should succeed.
     Promise.all([
@@ -49,3 +51,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links-ref.html
similarity index 60%
rename from third_party/blink/web_tests/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links-expected.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links-ref.html
index b7c9dbef..a743fd8 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: activatable allows anchor links (reference)</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 .spacer {
@@ -25,3 +30,4 @@
 <script>
 target.scrollIntoView();
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links.html
new file mode 100644
index 0000000..2d7f7154
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/activatable-locked-element-allows-anchor-links.html
@@ -0,0 +1,43 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: activatable allows anchor links</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="activatable-locked-element-allows-anchor-links-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+.spacer {
+  width: 150px;
+  height: 3000px;
+  background: lightblue;
+}
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightgreen;
+}
+#target {
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+
+<div class="spacer"></div>
+<div id="container"><div id="target"></div></div>
+
+<script>
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity, activatable: true }).then(() => {
+    location.href += "#target";
+    requestAnimationFrame(takeScreenshot);
+  });
+}
+
+window.onload = () => { requestAnimationFrame(runTest); };
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/commit-immediate-acquire-resolves-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/commit-immediate-acquire-resolves-ref.html
new file mode 100644
index 0000000..d55ac961
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/commit-immediate-acquire-resolves-ref.html
@@ -0,0 +1,19 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: commit, quick acquire (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="container"></div>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/commit-immediate-acquire-resolves.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/commit-immediate-acquire-resolves.html
similarity index 64%
rename from third_party/blink/web_tests/display-lock/lock-after-append/commit-immediate-acquire-resolves.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/commit-immediate-acquire-resolves.html
index cd3bb11..6f6fda38 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/commit-immediate-acquire-resolves.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/commit-immediate-acquire-resolves.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, and calls commit without waiting for the acquire promise.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: commit, quick acquire</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="commit-immediate-acquire-resolves-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -22,19 +25,14 @@
 <div id="container"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.getElementById("container");
+  const container = document.getElementById("container");
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
     container.displayLock.commit();
     container.displayLock.acquire({ timeout: Infinity }).then(() => {
@@ -47,3 +45,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/delayed-acquire-removes-painted-output-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/delayed-acquire-removes-painted-output-ref.html
new file mode 100644
index 0000000..a959aed
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/delayed-acquire-removes-painted-output-ref.html
@@ -0,0 +1,23 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire removes paint (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+}
+#checker {
+  width: 50px;
+  height: 50px;
+  background: green;
+}
+</style>
+
+<div id="container"></div>
+<div id="checker"></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/delayed-acquire-removes-painted-output.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/delayed-acquire-removes-painted-output.html
new file mode 100644
index 0000000..a3ba5779
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/delayed-acquire-removes-painted-output.html
@@ -0,0 +1,37 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire removes paint</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="delayed-acquire-removes-painted-output-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#checker {
+  width: 50px;
+  height: 50px;
+  background: green;
+}
+</style>
+
+<div id="container"></div>
+<div id="checker"></div>
+
+<script>
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(takeScreenshot);
+}
+
+window.onload = () => {
+  requestAnimationFrame(() => requestAnimationFrame(runTest));
+};
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-attribute.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-attribute.html
similarity index 64%
rename from third_party/blink/web_tests/display-lock/lock-after-append/locked-attribute.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-attribute.html
index b6ee881b..2f893ff0 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-attribute.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-attribute.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: locked attribute</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #container {
@@ -8,28 +13,28 @@
 
 <div id="container"></div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
   async function runTest() {
-    let container = document.getElementById("container");
+    const container = document.getElementById("container");
     t.step(() => assert_false(container.displayLock.locked, "initial context is unlocked"));
 
-    let acquire_promise = container.displayLock.acquire({ timeout: Infinity });
+    const acquire_promise = container.displayLock.acquire({ timeout: Infinity });
     t.step(() => assert_true(container.displayLock.locked, "context before acquire finishes is locked"));
 
     await acquire_promise;
     t.step(() => assert_true(container.displayLock.locked, "context after acquire finishes is locked"));
 
-    let update_promise = container.displayLock.update();
+    const update_promise = container.displayLock.update();
     t.step(() => assert_true(container.displayLock.locked, "context during update is locked"));
 
     await update_promise;
     t.step(() => assert_true(container.displayLock.locked, "context after update is locked"));
 
-    let commit_promise = container.displayLock.commit();
+    const commit_promise = container.displayLock.commit();
     t.step(() => assert_false(container.displayLock.locked, "context during commit is unlocked"));
 
     await commit_promise;
@@ -43,4 +48,4 @@
   };
 }, "locked attribute");
 </script>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-focus.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-focus.html
similarity index 64%
rename from third_party/blink/web_tests/display-lock/lock-after-append/locked-element-focus.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-focus.html
index ab5033e..c01558b2 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-focus.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-focus.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: </title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <div id="container" style ="contain:style layout">
   <div id="focusable" tabIndex="0">
@@ -6,14 +11,14 @@
   </div>
 </div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
 
   async function focusNonActivatableTest() {
-    let acquire_promise = container.displayLock.acquire({ timeout: Infinity });
+    const acquire_promise = container.displayLock.acquire({ timeout: Infinity });
     await acquire_promise;
     t.step(() => assert_not_equals(document.activeElement, focusable));
     focusable.focus();
@@ -23,7 +28,7 @@
 
   async function focusActivatableTest() {
     t.step(() => assert_not_equals(document.activeElement, focusable));
-    let acquire_promise = container.displayLock.acquire({ timeout: Infinity, activatable: true });
+    const acquire_promise = container.displayLock.acquire({ timeout: Infinity, activatable: true });
     await acquire_promise;
     focusable.focus();
     t.step(() => assert_equals(document.activeElement, focusable));
@@ -35,3 +40,4 @@
   };
 }, "Testing focus and force layout on element with locked flat-tree ancestor");
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-prevents-anchor-links.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-prevents-anchor-links.html
new file mode 100644
index 0000000..f0f3582
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-prevents-anchor-links.html
@@ -0,0 +1,43 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: anchor links prevented</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="spacer-and-container-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+.spacer {
+  width: 150px;
+  height: 3000px;
+  background: lightblue;
+}
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightgreen;
+}
+#target {
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+
+<div class="spacer"></div>
+<div id="container"><div id="target"></div></div>
+
+<script>
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => {
+    location.href += "#target";
+    requestAnimationFrame(takeScreenshot);
+  });
+}
+
+window.onload = () => { requestAnimationFrame(runTest); };
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-prevents-scroll-into-view.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-prevents-scroll-into-view.html
new file mode 100644
index 0000000..66e71f4
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-prevents-scroll-into-view.html
@@ -0,0 +1,43 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: scrollIntoView prevented</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="spacer-and-container-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+.spacer {
+  width: 150px;
+  height: 3000px;
+  background: lightblue;
+}
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightgreen;
+}
+#target {
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+
+<div class="spacer"></div>
+<div id="container"><div id="target"></div></div>
+
+<script>
+function runTest() {
+  const container = document.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => {
+    document.getElementById("target").scrollIntoView();
+    requestAnimationFrame(takeScreenshot);
+  });
+}
+
+window.onload = () => { requestAnimationFrame(runTest); };
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-shifted-down-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-shifted-down-ref.html
new file mode 100644
index 0000000..0b5affa
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-shifted-down-ref.html
@@ -0,0 +1,30 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: locked element shifted down (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+}
+#spacer {
+  width: 100px;
+  height: 100px;
+  background: lightgreen;
+}
+#checker {
+  width: 100px;
+  height: 50px;
+  background: green;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="spacer"></div>
+<div id="container"></div>
+<div id="checker"></div>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-shifted-down.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-shifted-down.html
similarity index 63%
rename from third_party/blink/web_tests/display-lock/lock-after-append/locked-element-shifted-down.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-shifted-down.html
index d8ed88b1..3dd70eb 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-element-shifted-down.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-element-shifted-down.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, then the element is shifted down by a div above.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: locked element shifted down</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="locked-element-shifted-down-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -29,19 +32,14 @@
 <div id="checker"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.getElementById("container");
+  const container = document.getElementById("container");
   container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => {
     document.getElementById("spacer").style.height = "100px";
     finishTest("PASS");
@@ -50,3 +48,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/locked-shadow-descendant.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-shadow-descendant.html
similarity index 75%
rename from third_party/blink/web_tests/display-lock/lock-after-append/locked-shadow-descendant.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-shadow-descendant.html
index f0a2f3c..64c595d0 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/locked-shadow-descendant.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/locked-shadow-descendant.html
@@ -1,11 +1,16 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: locked shadow descendant</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <div id="host">
   <input id="slotted" type="text">
 </div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 let container = document.createElement("div");
@@ -20,7 +25,7 @@
     t.step(() => assert_not_equals(document.activeElement, slotted));
     t.step(() => assert_not_equals(shadowRoot.activeElement, slotted));
 
-    let acquire_promise = container.displayLock.acquire({ timeout: Infinity });
+    const acquire_promise = container.displayLock.acquire({ timeout: Infinity });
     await acquire_promise;
 
     t.step(() => assert_not_equals(document.activeElement, slotted));
@@ -47,3 +52,4 @@
 }, "Testing focus and force layout on element with locked flat-tree ancestor");
 
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/measure-forced-layout-after-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-forced-layout-after-commit.html
similarity index 83%
rename from third_party/blink/web_tests/display-lock/lock-after-append/measure-forced-layout-after-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-forced-layout-after-commit.html
index 1556bf45..0cb1d21 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/measure-forced-layout-after-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-forced-layout-after-commit.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: measure forced layout after commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 .contained {
@@ -24,13 +29,13 @@
 <div id="parent"><div class="contained" id="small"><div id="large"></div></div></div>
 <div id="spacer"></div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
   function createChild(id) {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.classList = "child";
     child.id = id;
     return child;
@@ -67,7 +72,7 @@
   }
 
   async function runTest() {
-    let container = document.getElementById("small");
+    const container = document.getElementById("small");
     await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] });
 
     construct(document.getElementById("large"));
@@ -84,3 +89,4 @@
 }, "Measure Forced Layout");
 </script>
 
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/measure-forced-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-forced-layout.html
similarity index 83%
rename from third_party/blink/web_tests/display-lock/lock-after-append/measure-forced-layout.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-forced-layout.html
index b922f66..ef16011 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/measure-forced-layout.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-forced-layout.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: measure forced layout</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 .contained {
@@ -24,13 +29,13 @@
 <div id="parent"><div class="contained" id="small"><div id="large"></div></div></div>
 <div id="spacer"></div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
   function createChild(id) {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.classList = "child";
     child.id = id;
     return child;
@@ -67,7 +72,7 @@
   }
 
   async function runTest() {
-    let container = document.getElementById("small");
+    const container = document.getElementById("small");
     await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] });
 
     construct(document.getElementById("large"));
@@ -85,3 +90,4 @@
 }, "Measure Forced Layout");
 </script>
 
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/measure-updated-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-updated-layout.html
similarity index 84%
rename from third_party/blink/web_tests/display-lock/lock-after-append/measure-updated-layout.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-updated-layout.html
index e1102f8..3d2d94a 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/measure-updated-layout.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/measure-updated-layout.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: measure updated layout</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 .contained {
@@ -24,13 +29,13 @@
 <div id="parent"><div class="contained" id="small"><div id="large"></div></div></div>
 <div id="spacer"></div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
   function createChild(id) {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.classList = "child";
     child.id = id;
     return child;
@@ -67,7 +72,7 @@
   }
 
   async function runTest() {
-    let container = document.getElementById("small");
+    const container = document.getElementById("small");
     await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] });
 
     construct(document.getElementById("large"));
@@ -87,3 +92,4 @@
 }, "Measure Updated Layout");
 </script>
 
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/nested-acquire.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-acquire.html
similarity index 66%
rename from third_party/blink/web_tests/display-lock/lock-after-append/nested-acquire.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-acquire.html
index 8cf58c8..d0b59ba2 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/nested-acquire.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-acquire.html
@@ -1,4 +1,11 @@
 <!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: nested acquire</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 .container {
@@ -27,20 +34,15 @@
 </div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 async function runTest() {
-  let outer = document.getElementById("outer");
-  let inner = document.getElementById("inner");
+  const outer = document.getElementById("outer");
+  const inner = document.getElementById("inner");
 
   await outer.displayLock.acquire({ timeout: Infinity });
   // Dirty the inner layout
@@ -52,3 +54,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/nested-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-commit.html
similarity index 67%
rename from third_party/blink/web_tests/display-lock/lock-after-append/nested-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-commit.html
index d9a8f85..5b3d7ec 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/nested-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-commit.html
@@ -1,4 +1,11 @@
 <!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: nested commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 .container {
@@ -27,20 +34,15 @@
 </div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 async function runTest() {
-  let outer = document.getElementById("outer");
-  let inner = document.getElementById("inner");
+  const outer = document.getElementById("outer");
+  const inner = document.getElementById("inner");
 
   await Promise.all([
     outer.displayLock.acquire({ timeout: Infinity }),
@@ -54,3 +56,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-update-and-commit.html
new file mode 100644
index 0000000..b9e848b
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-update-and-commit.html
@@ -0,0 +1,61 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: nested updateAndCommit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+.container {
+  contain: style layout;
+}
+#outer {
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+#inner {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+div > div > div {
+  width: 10px;
+  height: 10px;
+  background: red;
+}
+</style>
+
+<div id="log"></div>
+<div id="outer" class="container">
+  <div id="inner" class="container"></div>
+</div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const outer = document.getElementById("outer");
+  const inner = document.getElementById("inner");
+
+  Promise.all([
+    outer.displayLock.acquire({ timeout: Infinity }),
+    inner.displayLock.acquire({ timeout: Infinity })])
+  .then(() =>  {
+    // Dirty the inner layout
+    inner.appendChild(document.createElement("div"));
+    inner.displayLock.updateAndCommit().then(
+      () => { finishTest("PASS"); },
+      (e) => { finishTest("FAIL " + e.message); });
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/nested-update.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-update.html
similarity index 67%
rename from third_party/blink/web_tests/display-lock/lock-after-append/nested-update.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-update.html
index f3f7ea0..e8b1513 100644
--- a/third_party/blink/web_tests/display-lock/lock-after-append/nested-update.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/nested-update.html
@@ -1,4 +1,11 @@
 <!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: nested update</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 .container {
@@ -27,20 +34,15 @@
 </div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 async function runTest() {
-  let outer = document.getElementById("outer");
-  let inner = document.getElementById("inner");
+  const outer = document.getElementById("outer");
+  const inner = document.getElementById("inner");
 
   await Promise.all([
     outer.displayLock.acquire({ timeout: Infinity }),
@@ -54,3 +56,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-container-with-child-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-container-with-child-ref.html
new file mode 100644
index 0000000..df8fbf42
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-container-with-child-ref.html
@@ -0,0 +1,24 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: pass, container with child (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="container"><div id="child"></div></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-no-containment-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-no-containment-ref.html
new file mode 100644
index 0000000..9cce14b2
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-no-containment-ref.html
@@ -0,0 +1,18 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: pass, no containment (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log">PASS Containment requirement is not satisfied.</div>
+<div id="container"></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-ref.html
new file mode 100644
index 0000000..2df7d74c
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/pass-ref.html
@@ -0,0 +1,9 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: pass (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<div id="log">PASS</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/spacer-and-container-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/spacer-and-container-ref.html
new file mode 100644
index 0000000..73980d2d
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/spacer-and-container-ref.html
@@ -0,0 +1,23 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: spacer and a container (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+.spacer {
+  width: 150px;
+  height: 3000px;
+  background: lightblue;
+}
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+}
+</style>
+
+<div class="spacer"></div>
+<div id="container"></div>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-clone.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-clone.html
similarity index 64%
rename from third_party/blink/web_tests/display-lock/lock-before-append/acquire-clone.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-clone.html
index 0f501ea..494ca19 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-clone.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-clone.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire on a clone</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #container {
@@ -14,16 +19,16 @@
 }
 </style>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
   async function runTest() {
-    let container = document.createElement("div");
+    const container = document.createElement("div");
     // Lock the container, put a child into it and put it into the document.
     await container.displayLock.acquire({ timeout: Infinity }).then(() => {
-      let child = document.createElement("div");
+      const child = document.createElement("div");
       child.id = "child";
       container.appendChild(child);
 
@@ -31,7 +36,7 @@
       document.body.appendChild(container);
     });
     // Make a copy of the container and put it in the document as well.
-    let cloned = container.cloneNode(true);
+    const cloned = container.cloneNode(true);
     document.body.appendChild(cloned);
 
     t.step(() => {
@@ -43,3 +48,4 @@
   window.onload = runTest;
 });
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-commit.html
similarity index 62%
rename from third_party/blink/web_tests/display-lock/lock-before-append/acquire-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-commit.html
index e867935..10587f8 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-commit.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, appends a child, and calls commit.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -21,21 +24,16 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.id = "child";
     container.appendChild(child);
 
@@ -50,3 +48,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-infinite-timeout-no-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-infinite-timeout-no-commit.html
new file mode 100644
index 0000000..30c9c57
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-infinite-timeout-no-commit.html
@@ -0,0 +1,40 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire infinite timeout</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.id = "container";
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    document.body.appendChild(container);
+    setTimeout(() => { finishTest("PASS"); }, 100);
+  });
+}
+
+window.onload = runTest;
+</script>
+
+
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-timeout-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-timeout-ref.html
new file mode 100644
index 0000000..983dc28
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-timeout-ref.html
@@ -0,0 +1,18 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire times out (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+</style>
+<div id="log">PASS if container is visible</div>
+<div id="container"></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-timeout.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-timeout.html
new file mode 100644
index 0000000..eed45bef
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-timeout.html
@@ -0,0 +1,40 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire times out</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-timeout-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.id = "container";
+
+  container.displayLock.acquire({ timeout: 100 }).then(() => {
+    document.body.appendChild(container);
+    setTimeout(() => { finishTest("PASS if container is visible"); }, 200);
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-and-commit.html
similarity index 62%
rename from third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-and-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-and-commit.html
index d8df777..76017f30 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-and-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-and-commit.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, appends a child, and calls updateAndCommit.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, updateAndCommit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -21,21 +24,16 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.id = "child";
     container.appendChild(child);
 
@@ -50,3 +48,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-commit.html
similarity index 63%
rename from third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-commit.html
index 8141a62..58f1836 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-commit.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, appends a child, and calls update, and then commit.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, update, commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -21,21 +24,16 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.id = "child";
     container.appendChild(child);
 
@@ -52,3 +50,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-measure-remove-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-measure-remove-ref.html
new file mode 100644
index 0000000..9ba0a916
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-measure-remove-ref.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire, update, measure, remove (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#spacer {
+  width: 150px;
+  height: 150px;
+  background: green;
+}
+</style>
+
+<div id="spacer"></div>
+<div id="log">0 20 40 8 8</div>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-measure-remove.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-measure-remove.html
similarity index 68%
rename from third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-measure-remove.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-measure-remove.html
index 1566d85f..0baa41e 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-measure-remove.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-measure-remove.html
@@ -1,9 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs acquire, constructs a subtree, calls update and measures it in
-the promise resolotion, which also removes the element from the DOM.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, update, measure, remove</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-update-measure-remove-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -35,16 +37,8 @@
 <div id="log"></div>
 
 <script>
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finish() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
 function measureAndRemove() {
-  let log = document.getElementById("log");
+  const log = document.getElementById("log");
   log.innerHTML += "" + document.getElementById("0").offsetTop;
   log.innerHTML += " " + document.getElementById("1").offsetTop;
   log.innerHTML += " " + document.getElementById("2").offsetTop;
@@ -54,14 +48,14 @@
 }
 
 function createChild(id) {
-  let child = document.createElement("div");
+  const child = document.createElement("div");
   child.classList = "child";
   child.id = id;
   return child;
 }
 
 function construct(container) {
-  let sizer = document.createElement("div");
+  const sizer = document.createElement("div");
   sizer.id = "sizer";
   container.appendChild(sizer);
   sizer.appendChild(createChild("0"));
@@ -70,15 +64,16 @@
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.id = "container";
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
     construct(container);
     document.getElementById("empty").appendChild(container);
-    container.displayLock.update().then(measureAndRemove).then(finish);
+    container.displayLock.update().then(measureAndRemove).then(takeScreenshot);
   });
 }
 
 window.onload = runTest;
 </script>
 
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-commit-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-commit-ref.html
new file mode 100644
index 0000000..0650cf1
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-commit-ref.html
@@ -0,0 +1,20 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire, update, remove, commit (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+</style>
+
+<div id="log">PASS Element is disconnected.</div>
+<div id="container"></div>
+
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-commit.html
similarity index 63%
rename from third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-commit.html
index 43c92b1..6ef1be9 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-commit.html
@@ -1,9 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire(), then update(), then removes the element, and calls commit.
-Update promise should reject.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, update, remove, commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-update-remove-commit-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -17,19 +19,14 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.id = "container";
 
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
@@ -47,3 +44,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-ref.html
new file mode 100644
index 0000000..646c605
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove-ref.html
@@ -0,0 +1,9 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire, update, remove (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<div id="log">PASS Element is disconnected.</div>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove.html
similarity index 61%
rename from third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove.html
index ef43615..743468a 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/acquire-update-remove.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/acquire-update-remove.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire(), then calls update() but disconnects the element before update finishes.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, update, remove</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-update-remove-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -16,19 +19,14 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.id = "container";
 
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
@@ -42,3 +40,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-followed-by-update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-followed-by-update-and-commit.html
new file mode 100644
index 0000000..76752c04
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-followed-by-update-and-commit.html
@@ -0,0 +1,51 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: commit, updateAndCommit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    const child = document.createElement("div");
+    child.id = "child";
+    container.appendChild(child);
+
+    container.id = "container";
+    document.body.appendChild(container);
+
+    const first_promise = container.displayLock.commit();
+    const second_promise = container.displayLock.updateAndCommit();
+    Promise.all([first_promise, second_promise]).then(() => finishTest("PASS"));
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-added-containment-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-added-containment-ref.html
new file mode 100644
index 0000000..0d93404e
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-added-containment-ref.html
@@ -0,0 +1,18 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: commit after containment added (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+.contained {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+</style>
+<div id="log">PASS</div>
+<div class="contained"></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-added-containment.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-added-containment.html
new file mode 100644
index 0000000..14b1309f
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-added-containment.html
@@ -0,0 +1,41 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: commit after containment added</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="commit-on-added-containment-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+.contained {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+</style>
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    container.classList = "contained";
+    document.body.appendChild(container);
+
+    container.displayLock.commit().then(
+      () => { finishTest("PASS"); },
+      (e) => { finishTest("FAIL " + e.message); });
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-inline-fails.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-inline-fails.html
new file mode 100644
index 0000000..7f14d481
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-inline-fails.html
@@ -0,0 +1,38 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: commit on inline</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-no-containment-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function acquire() {
+  const container = document.createElement("span");
+  container.id = "container";
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    document.body.appendChild(container);
+    container.displayLock.commit().then(
+      () => { finishTest("FAIL"); },
+      (e) => { finishTest("PASS " + e.message); });
+  });
+}
+
+window.onload = acquire;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-no-containment-fails.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-no-containment-fails.html
new file mode 100644
index 0000000..8c09185a
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-on-no-containment-fails.html
@@ -0,0 +1,32 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: commit without containment</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-no-containment-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function acquire() {
+  const container = document.createElement("div");
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    document.body.appendChild(container);
+    container.displayLock.commit().then(
+      () => { finishTest("FAIL"); },
+      (e) => { finishTest("PASS " + e.message); });
+  });
+}
+
+window.onload = acquire;
+</script>
+
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-while-disconnected-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-while-disconnected-ref.html
new file mode 100644
index 0000000..70d99e1
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-while-disconnected-ref.html
@@ -0,0 +1,19 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: commit while disconnected (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="container"></div>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-while-disconnected.html
similarity index 60%
rename from third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-while-disconnected.html
index c386c96..a2dc7f5 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-while-disconnected.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire(), then commits without connecting the element, which should just unlock and fail.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: commit while disconnected</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="commit-while-disconnected-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -16,19 +19,14 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.id = "container";
 
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
@@ -43,3 +41,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-without-acquire-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-without-acquire-ref.html
new file mode 100644
index 0000000..2a9e5677
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-without-acquire-ref.html
@@ -0,0 +1,19 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: commit without acquire (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="container"></div>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-without-acquire.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-without-acquire.html
similarity index 60%
rename from third_party/blink/web_tests/display-lock/lock-before-append/commit-without-acquire.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-without-acquire.html
index 784f7cd..7dc6653 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/commit-without-acquire.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/commit-without-acquire.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Calls commit without first acquiring, which fails.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: commit without acquire</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="commit-without-acquire-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -21,19 +24,14 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.id = "container";
   container.displayLock.commit().then(
       () => { finishTest("PASS"); },
@@ -43,3 +41,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/display-none-ancestor-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/display-none-ancestor-ref.html
new file mode 100644
index 0000000..51904c6
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/display-none-ancestor-ref.html
@@ -0,0 +1,25 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: display none ancestor (reference)</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  width: 200px;
+  height: 200px;
+  background: green;
+}
+
+#locked {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="container"><div id="locked"></div></div>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/display-none-ancestor.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/display-none-ancestor.html
similarity index 68%
rename from third_party/blink/web_tests/display-lock/lock-before-append/display-none-ancestor.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/display-none-ancestor.html
index 58cf20aa..133bca6c 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/display-none-ancestor.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/display-none-ancestor.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Commit a locked element that was previously under a display:none tree.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: display none ancestor</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="display-none-ancestor-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -23,19 +26,14 @@
 <div id="container" style="display:none;"></div>
 
 <script>
-// TODO(rakina): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let locked = document.createElement("div");
+  const locked = document.createElement("div");
   locked.id = "locked";
   locked.displayLock.acquire({ timeout: Infinity }).then(() => {
     container.appendChild(locked);
@@ -53,3 +51,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/element-in-template.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/element-in-template.html
similarity index 81%
rename from third_party/blink/web_tests/display-lock/lock-before-append/element-in-template.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/element-in-template.html
index f7c9ef8..0dfc95c77 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/element-in-template.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/element-in-template.html
@@ -1,7 +1,12 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: element in template</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <style>
   div {
@@ -49,3 +54,4 @@
 }, "Testing locking element in templates");
 
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/locked-attribute.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/locked-attribute.html
similarity index 66%
rename from third_party/blink/web_tests/display-lock/lock-before-append/locked-attribute.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/locked-attribute.html
index 6e0c136..70161b6d 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/locked-attribute.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/locked-attribute.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: locked property</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #container {
@@ -8,17 +13,17 @@
 
 <div id="parent"></div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
   async function runTest() {
-    let container = document.createElement("div");
+    const container = document.createElement("div");
     container.id = "container";
     assert_false(container.displayLock.locked, "initial context is unlocked");
 
-    let acquire_promise = container.displayLock.acquire({ timeout: Infinity });
+    const acquire_promise = container.displayLock.acquire({ timeout: Infinity });
     t.step(() => assert_true(container.displayLock.locked, "context before acquire finishes is locked"));
 
     await acquire_promise;
@@ -26,13 +31,13 @@
 
     document.getElementById("parent").appendChild(container);
 
-    let update_promise = container.displayLock.update();
+    const update_promise = container.displayLock.update();
     t.step(() => assert_true(container.displayLock.locked, "context during update is locked"));
 
     await update_promise;
     t.step(() => assert_true(container.displayLock.locked, "context after update is locked"));
 
-    let commit_promise = container.displayLock.commit();
+    const commit_promise = container.displayLock.commit();
     t.step(() => assert_false(container.displayLock.locked, "context during commit is unlocked"));
 
     await commit_promise;
@@ -47,3 +52,4 @@
 }, "locked attribute");
 </script>
 
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/locked-shadow-descendant.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/locked-shadow-descendant.html
similarity index 71%
rename from third_party/blink/web_tests/display-lock/lock-before-append/locked-shadow-descendant.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/locked-shadow-descendant.html
index e176c14..a215f1d 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/locked-shadow-descendant.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/locked-shadow-descendant.html
@@ -1,27 +1,32 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: locked shadow descendant</title>
+<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <div id="host">
   <input id="slotted" type="text"/>
 </div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.id = "container";
   container.style = "contain: style layout;";
   container.innerHTML = "<slot></slot>";
 
-  let shadowRoot = host.attachShadow({ mode: "open" });
+  const shadowRoot = host.attachShadow({ mode: "open" });
 
   async function focusTest() {
     t.step(() => assert_not_equals(document.activeElement, slotted));
     t.step(() => assert_not_equals(shadowRoot.activeElement, slotted));
     t.step(() => assert_not_equals(container.displayLock, null));
 
-    let acquire_promise = container.displayLock.acquire({ timeout: Infinity });
+    const acquire_promise = container.displayLock.acquire({ timeout: Infinity });
 
     await acquire_promise;
     shadowRoot.appendChild(container);
@@ -50,3 +55,4 @@
 }, "Testing focus and force layout on element with locked flat-tree ancestor");
 
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/measure-forced-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-forced-layout.html
similarity index 82%
rename from third_party/blink/web_tests/display-lock/lock-before-append/measure-forced-layout.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-forced-layout.html
index 0fede37..c39f007 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/measure-forced-layout.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-forced-layout.html
@@ -1,10 +1,9 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, which constructs and measures a subtree.
-This should do a forced layout. Commit also measures it to get
-post-final-layout values.
--->
+<html>
+<meta charset="utf8">
+<title>Display Locking: measure forced layout</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #container {
@@ -30,13 +29,13 @@
 <div id="parent"></div>
 <div id="spacer"></div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
   function createChild(id) {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.classList = "child";
     child.id = id;
     return child;
@@ -68,7 +67,7 @@
   }
 
   function construct(container) {
-    let sizer = document.createElement("div");
+    const sizer = document.createElement("div");
     sizer.id = "sizer";
     container.appendChild(sizer);
     sizer.appendChild(createChild("0"));
@@ -77,7 +76,7 @@
   }
 
   async function runTest() {
-    let container = document.createElement("div");
+    const container = document.createElement("div");
     container.id = "container";
     await container.displayLock.acquire({ timeout: Infinity });
 
@@ -97,3 +96,4 @@
 }, "Measure Forced Layout");
 </script>
 
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/measure-forced-svg-text.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-forced-svg-text.html
similarity index 76%
rename from third_party/blink/web_tests/display-lock/lock-before-append/measure-forced-svg-text.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-forced-svg-text.html
index 00f2143..6d25606 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/measure-forced-svg-text.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-forced-svg-text.html
@@ -1,10 +1,9 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, which constructs and measures a subtree.
-This should do a forced layout. Commit also measures it to get
-post-final-layout values.
--->
+<html>
+<meta charset="utf8">
+<title>Display Locking: measure forced SVG text</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #container {
@@ -17,8 +16,8 @@
 
 <div id="parent"></div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
@@ -46,7 +45,7 @@
   }
 
   async function runTest() {
-    let container = document.createElement("div");
+    const container = document.createElement("div");
     container.id = "container";
     await container.displayLock.acquire({ timeout: Infinity });
 
@@ -66,3 +65,4 @@
 }, "Measure Forced SVG Text");
 </script>
 
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/measure-updated-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-updated-layout.html
similarity index 83%
rename from third_party/blink/web_tests/display-lock/lock-before-append/measure-updated-layout.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-updated-layout.html
index f5a82db..a011acf 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/measure-updated-layout.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/measure-updated-layout.html
@@ -1,10 +1,9 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, which constructs and measures a subtree.
-This should do a forced layout. Commit also measures it to get
-post-final-layout values.
--->
+<html>
+<meta charset="utf8">
+<title>Display Locking: measure updated layout</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #container {
@@ -30,20 +29,20 @@
 <div id="parent"></div>
 <div id="spacer"></div>
 
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <script>
 async_test((t) => {
   function createChild(id) {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.classList = "child";
     child.id = id;
     return child;
   }
 
   function construct(container) {
-    let sizer = document.createElement("div");
+    const sizer = document.createElement("div");
     sizer.id = "sizer";
     container.appendChild(sizer);
     sizer.appendChild(createChild("0"));
@@ -77,7 +76,7 @@
   }
 
   async function runTest() {
-    let container = document.createElement("div");
+    const container = document.createElement("div");
     container.id = "container";
     await container.displayLock.acquire({ timeout: Infinity });
 
@@ -98,4 +97,4 @@
   };
 }, "Measure Updated Layout");
 </script>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/multiple-acquires-all-succeed.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/multiple-acquires-all-succeed.html
similarity index 70%
rename from third_party/blink/web_tests/display-lock/lock-before-append/multiple-acquires-all-succeed.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/multiple-acquires-all-succeed.html
index c0535f2..e867570 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/multiple-acquires-all-succeed.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/multiple-acquires-all-succeed.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs multiple acquires and updates.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: multiple acquires and updates</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -21,26 +24,21 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   Promise.all([
     container.displayLock.acquire({ timeout: Infinity }),
     container.displayLock.acquire({ timeout: Infinity }),
     container.displayLock.acquire({ timeout: Infinity }),
     container.displayLock.acquire({ timeout: Infinity })
   ]).then(() => {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.id = "child";
     container.appendChild(child);
 
@@ -62,3 +60,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/multiple-update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/multiple-update-and-commit.html
similarity index 61%
rename from third_party/blink/web_tests/display-lock/lock-before-append/multiple-update-and-commit.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/multiple-update-and-commit.html
index f881f209..cbb480c9 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/multiple-update-and-commit.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/multiple-update-and-commit.html
@@ -1,4 +1,11 @@
 <!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: multiple updateAndCommit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -17,28 +24,23 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.id = "child";
     container.appendChild(child);
 
     container.id = "container";
     document.body.appendChild(container);
 
-    let promises = []
+    const promises = []
     for (let i = 0; i < 10; ++i) {
       promises.push(container.displayLock.updateAndCommit());
     }
@@ -48,3 +50,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-container-with-child-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-container-with-child-ref.html
new file mode 100644
index 0000000..c5019c4
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-container-with-child-ref.html
@@ -0,0 +1,24 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: pass, container with child</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log">PASS</div>
+<div id="container"><div id="child"></div></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-no-containment-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-no-containment-ref.html
new file mode 100644
index 0000000..c903d9c
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-no-containment-ref.html
@@ -0,0 +1,9 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: pass, no containment (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<div id="log">PASS Containment requirement is not satisfied.</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-ref.html
new file mode 100644
index 0000000..59f637c
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/pass-ref.html
@@ -0,0 +1,9 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: pass (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<div>PASS</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/timeout-while-disconnected-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/timeout-while-disconnected-ref.html
new file mode 100644
index 0000000..039f800
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/timeout-while-disconnected-ref.html
@@ -0,0 +1,19 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: timeout while disconnected (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+</style>
+<div id="log">PASS if container is visible</div>
+<div id="container"></div>
+
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/timeout-while-disconnected.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/timeout-while-disconnected.html
new file mode 100644
index 0000000..424bbe5
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/timeout-while-disconnected.html
@@ -0,0 +1,42 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: timeout while disconnected</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="timeout-while-disconnected-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+  background: lightblue;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.id = "container";
+
+  container.displayLock.acquire({ timeout: 100 }).then(() => {
+    setTimeout(() => {
+      document.body.appendChild(container);
+      finishTest("PASS if container is visible");
+    }, 200);
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit-followed-by-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit-followed-by-commit.html
new file mode 100644
index 0000000..f66a4c8
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit-followed-by-commit.html
@@ -0,0 +1,51 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: updateAndCommit, commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    const child = document.createElement("div");
+    child.id = "child";
+    container.appendChild(child);
+
+    container.id = "container";
+    document.body.appendChild(container);
+
+    const first_promise = container.displayLock.updateAndCommit();
+    const second_promise = container.displayLock.commit();
+    Promise.all([first_promise, second_promise]).then(() => finishTest("PASS"));
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit-followed-by-update.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit-followed-by-update.html
new file mode 100644
index 0000000..877492cd
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit-followed-by-update.html
@@ -0,0 +1,51 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: updateAndCommit, update</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    const child = document.createElement("div");
+    child.id = "child";
+    container.appendChild(child);
+
+    container.id = "container";
+    document.body.appendChild(container);
+
+    const first_promise = container.displayLock.updateAndCommit();
+    const second_promise = container.displayLock.update();
+    Promise.all([first_promise, second_promise]).then(() => finishTest("PASS"));
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit.html
new file mode 100644
index 0000000..a18983da
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-and-commit.html
@@ -0,0 +1,38 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: updateAndCommit without acquire</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.id = "container";
+  container.displayLock.updateAndCommit().then(
+    () => { finishTest("PASS"); },
+    (e) => { finishTest("FAIL " + e.message); });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-followed-by-update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-followed-by-update-and-commit.html
new file mode 100644
index 0000000..1474854
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-followed-by-update-and-commit.html
@@ -0,0 +1,51 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: update, updateAndCommit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    const child = document.createElement("div");
+    child.id = "child";
+    container.appendChild(child);
+
+    container.id = "container";
+    document.body.appendChild(container);
+
+    const first_promise = container.displayLock.update();
+    const second_promise = container.displayLock.updateAndCommit();
+    Promise.all([first_promise, second_promise]).then(() => finishTest("PASS"));
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-together-with-commit-both-succeed.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-together-with-commit-both-succeed.html
similarity index 63%
rename from third_party/blink/web_tests/display-lock/lock-before-append/update-together-with-commit-both-succeed.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-together-with-commit-both-succeed.html
index 38222ae..60c9c3b 100644
--- a/third_party/blink/web_tests/display-lock/lock-before-append/update-together-with-commit-both-succeed.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-together-with-commit-both-succeed.html
@@ -1,8 +1,11 @@
 <!doctype HTML>
-
-<!--
-Runs an acquire, then update and commit synchronously, both should succeed.
--->
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire, update+commit</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="pass-container-with-child-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #container {
@@ -21,21 +24,16 @@
 <div id="log"></div>
 
 <script>
-// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
 function finishTest(status_string) {
   if (document.getElementById("log").innerHTML === "")
     document.getElementById("log").innerHTML = status_string;
-  if (window.testRunner)
-    window.testRunner.notifyDone();
+  takeScreenshot();
 }
 
 function runTest() {
-  let container = document.createElement("div");
+  const container = document.createElement("div");
   container.displayLock.acquire({ timeout: Infinity }).then(() => {
-    let child = document.createElement("div");
+    const child = document.createElement("div");
     child.id = "child";
     container.appendChild(child);
 
@@ -52,3 +50,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-while-disconnected-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-while-disconnected-ref.html
new file mode 100644
index 0000000..3743163ee
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-while-disconnected-ref.html
@@ -0,0 +1,9 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: update while disconnected (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<div id="log">PASS Element is unlocked.</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-while-disconnected.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-while-disconnected.html
new file mode 100644
index 0000000..1989f0c8
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-while-disconnected.html
@@ -0,0 +1,32 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: update while disconnected</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="update-while-disconnected-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.id = "container";
+
+  container.displayLock.acquire({ timeout: Infinity }).then(() => {
+    container.displayLock.update().then(
+      () => { finishTest("FAIL"); },
+      (e) => { finishTest("PASS " + e.message); });
+  });
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-without-acquire-fails-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-without-acquire-fails-ref.html
new file mode 100644
index 0000000..d54ca271
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-without-acquire-fails-ref.html
@@ -0,0 +1,19 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: update without acquire (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+</style>
+
+<div id="log">PASS Element is unlocked.</div>
+<div id="container"></div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-without-acquire-fails.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-without-acquire-fails.html
new file mode 100644
index 0000000..b51971e
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-before-append/update-without-acquire-fails.html
@@ -0,0 +1,44 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: update without acquire</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="update-without-acquire-fails-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#container {
+  contain: style layout;
+  width: 150px;
+  height: 150px;
+  background: lightblue;
+}
+#child {
+  width: 50px;
+  height: 50px;
+  background: lightgreen;
+}
+</style>
+
+<div id="log"></div>
+
+<script>
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  takeScreenshot();
+}
+
+function runTest() {
+  const container = document.createElement("div");
+  container.id = "container";
+  container.displayLock.update().then(
+      () => { finishTest("FAIL"); },
+      (e) => { finishTest("PASS " + e.message); });
+  document.body.appendChild(container);
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars-ref.html
new file mode 100644
index 0000000..55eaf23
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars-ref.html
@@ -0,0 +1,30 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire() size + border + scrollbars (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  visibility: hidden;
+  overflow: scroll;
+  border: 10px solid black;
+}
+#sizer {
+  width: 123px;
+  height: 456px;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="sizer"></div>
+  </div>
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html
new file mode 100644
index 0000000..5e561d0
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html
@@ -0,0 +1,43 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire() size + border + scrollbars</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-size-used-when-auto-size-border-and-scrollbars-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  overflow: scroll;
+  border: 10px solid black;
+}
+#child {
+  width: 500px;
+  height: 500px;
+  background: red;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="child"></div>
+  </div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content.html
similarity index 63%
rename from third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content.html
index b01edda..be64a72 100644
--- a/third_party/blink/web_tests/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-min-content.html
@@ -1,4 +1,11 @@
 <!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire() size + border, with min-content</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-size-used-when-auto-size-border-ref.html">
+<script src="/common/reftest-wait.js"></script>
 
 <style>
 #border {
@@ -39,3 +46,4 @@
 
 window.onload = runTest;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-ref.html
new file mode 100644
index 0000000..978d57a
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border-ref.html
@@ -0,0 +1,29 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire() size + border (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  visibility: hidden;
+  border: 10px solid black;
+}
+#sizer {
+  width: 123px;
+  height: 456px;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="sizer"></div>
+  </div>
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border.html
new file mode 100644
index 0000000..90c7eae
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-border.html
@@ -0,0 +1,42 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire() size + border</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-size-used-when-auto-size-border-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  border: 10px solid black;
+}
+#child {
+  width: 500px;
+  height: 500px;
+  background: red;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="child"></div>
+  </div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-ref.html
new file mode 100644
index 0000000..5612a1b
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-ref.html
@@ -0,0 +1,27 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire() size (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+}
+#sizer {
+  width: 123px;
+  height: 456px;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="sizer"></div>
+  </div>
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars-ref.html
new file mode 100644
index 0000000..bd7ceca4
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars-ref.html
@@ -0,0 +1,29 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: acquire() size + scrollbars (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  visibility: hidden;
+  overflow: scroll;
+}
+#sizer {
+  width: 123px;
+  height: 456px;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="sizer"></div>
+  </div>
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars.html
new file mode 100644
index 0000000..8b33792
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size-scrollbars.html
@@ -0,0 +1,42 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire() size + scrollbars</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-size-used-when-auto-size-scrollbars-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  overflow: scroll;
+}
+#child {
+  width: 500px;
+  height: 500px;
+  background: red;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="child"></div>
+  </div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size.html
new file mode 100644
index 0000000..5a83fc11
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/acquire-size-used-when-auto-size.html
@@ -0,0 +1,41 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: acquire() size</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="acquire-size-used-when-auto-size-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+}
+#child {
+  width: 500px;
+  height: 500px;
+  background: red;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="child"></div>
+  </div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-ref.html
similarity index 65%
copy from third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow-expected.html
copy to third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-ref.html
index f8123f1..ee42c4e 100644
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: flex column, horizontal-tb (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #flexer {
@@ -12,7 +17,6 @@
 }
 #container {
   contain: style layout;
-  flex-grow: 3;
 }
 #child {
   width: 12px;
@@ -22,7 +26,6 @@
   width: 50px;
   height: 60px;
   background: blue;
-  flex-grow: 1;
 }
 </style>
 
@@ -31,4 +34,4 @@
   <div id="container"><div id="child"></div></div>
   <div class="item"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-with-grow-ref.html
similarity index 66%
rename from third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow-expected.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-with-grow-ref.html
index f8123f1..5497c1f 100644
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-horizontal-with-grow-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-with-grow-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: flex column with grow, horizontal-tb (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #flexer {
@@ -31,4 +36,4 @@
   <div id="container"><div id="child"></div></div>
   <div class="item"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-with-grow.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-with-grow.html
new file mode 100644
index 0000000..27aa12a
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal-with-grow.html
@@ -0,0 +1,48 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: flex column with grow, horizontal-tb</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="flex-column-horizontal-with-grow-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#flexer {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  width: 200px;
+  height: 200px;
+  background: lightgreen;
+  writing-mode: horizontal-tb;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  flex-grow: 3;
+}
+.item {
+  width: 50px;
+  height: 60px;
+  background: blue;
+  flex-grow: 1;
+}
+</style>
+
+<div id="flexer">
+  <div class="item"></div>
+  <div id="container"></div>
+  <div class="item"></div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal.html
new file mode 100644
index 0000000..be09ab5
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-horizontal.html
@@ -0,0 +1,47 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: flex column, horizontal-tb</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="flex-column-horizontal-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#flexer {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  width: 200px;
+  height: 200px;
+  background: lightgreen;
+  writing-mode: horizontal-tb;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+}
+.item {
+  width: 50px;
+  height: 60px;
+  background: blue;
+}
+</style>
+
+<div id="flexer">
+  <div class="item"></div>
+  <div id="container"></div>
+  <div class="item"></div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-ref.html
similarity index 65%
rename from third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-expected.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-ref.html
index 5c35a431..5cda0b94 100644
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: flex column, vertical-rl (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #flexer {
@@ -29,4 +34,4 @@
   <div id="container"><div id="child"></div></div>
   <div class="item"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-with-grow-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-with-grow-ref.html
similarity index 66%
rename from third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-with-grow-expected.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-with-grow-ref.html
index 2dc267a..01c3741 100644
--- a/third_party/blink/web_tests/display-lock/sizing/flex-column-vertical-with-grow-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-with-grow-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: flex column with grow, vertical-rl (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #flexer {
@@ -31,4 +36,4 @@
   <div id="container"><div id="child"></div></div>
   <div class="item"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-with-grow.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-with-grow.html
new file mode 100644
index 0000000..9956c999
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical-with-grow.html
@@ -0,0 +1,48 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: flex column with grow, vertical-rl</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="flex-column-vertical-with-grow-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#flexer {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  width: 200px;
+  height: 200px;
+  background: lightgreen;
+  writing-mode: vertical-rl;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  flex-grow: 3;
+}
+.item {
+  width: 50px;
+  height: 60px;
+  background: blue;
+  flex-grow: 1;
+}
+</style>
+
+<div id="flexer">
+  <div class="item"></div>
+  <div id="container"></div>
+  <div class="item"></div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical.html
new file mode 100644
index 0000000..ae01c7f4f
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-column-vertical.html
@@ -0,0 +1,46 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: flex column, vertical-rl</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="flex-column-vertical-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#flexer {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  width: 200px;
+  height: 200px;
+  background: lightgreen;
+  writing-mode: vertical-rl;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+}
+.item {
+  width: 50px;
+  height: 60px;
+  background: blue;
+}
+</style>
+
+<div id="flexer">
+  <div class="item"></div>
+  <div id="container"></div>
+  <div class="item"></div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-ref.html
similarity index 65%
copy from third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow-expected.html
copy to third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-ref.html
index 1a2cdcb1..89307899 100644
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: flex row, horizontal-tb (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #flexer {
@@ -12,7 +17,6 @@
 }
 #container {
   contain: style layout;
-  flex-grow: 3;
 }
 #child {
   width: 12px;
@@ -22,7 +26,6 @@
   width: 50px;
   height: 60px;
   background: blue;
-  flex-grow: 1;
 }
 </style>
 
@@ -31,4 +34,4 @@
   <div id="container"><div id="child"></div></div>
   <div class="item"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-with-grow-ref.html
similarity index 66%
rename from third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow-expected.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-with-grow-ref.html
index 1a2cdcb1..6339313 100644
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-horizontal-with-grow-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-with-grow-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: flex row with grow, horizontal-tb (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #flexer {
@@ -31,4 +36,4 @@
   <div id="container"><div id="child"></div></div>
   <div class="item"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-with-grow.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-with-grow.html
new file mode 100644
index 0000000..7165435
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal-with-grow.html
@@ -0,0 +1,48 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: flex row with grow, horizontal-tb</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="flex-row-horizontal-with-grow-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#flexer {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+  width: 200px;
+  height: 200px;
+  background: lightgreen;
+  writing-mode: horizontal-tb;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  flex-grow: 3;
+}
+.item {
+  width: 50px;
+  height: 60px;
+  background: blue;
+  flex-grow: 1;
+}
+</style>
+
+<div id="flexer">
+  <div class="item"></div>
+  <div id="container"></div>
+  <div class="item"></div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal.html
new file mode 100644
index 0000000..7a4117c7
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-horizontal.html
@@ -0,0 +1,46 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: flex row, horizontal-tb</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="flex-row-horizontal-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#flexer {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+  width: 200px;
+  height: 200px;
+  background: lightgreen;
+  writing-mode: horizontal-tb;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+}
+.item {
+  width: 50px;
+  height: 60px;
+  background: blue;
+}
+</style>
+
+<div id="flexer">
+  <div class="item"></div>
+  <div id="container"></div>
+  <div class="item"></div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-ref.html
similarity index 65%
copy from third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow-expected.html
copy to third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-ref.html
index 425ae927..e532cc52 100644
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: flex row, vertical-rl (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #flexer {
@@ -12,7 +17,6 @@
 }
 #container {
   contain: style layout;
-  flex-grow: 3;
 }
 #child {
   width: 12px;
@@ -22,7 +26,6 @@
   width: 50px;
   height: 60px;
   background: blue;
-  flex-grow: 1;
 }
 </style>
 
@@ -31,4 +34,4 @@
   <div id="container"><div id="child"></div></div>
   <div class="item"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-with-grow-ref.html
similarity index 66%
rename from third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow-expected.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-with-grow-ref.html
index 425ae927..994e774 100644
--- a/third_party/blink/web_tests/display-lock/sizing/flex-row-vertical-with-grow-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-with-grow-ref.html
@@ -1,4 +1,9 @@
 <!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: flex row with grow, vertical-rl (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
 
 <style>
 #flexer {
@@ -31,4 +36,4 @@
   <div id="container"><div id="child"></div></div>
   <div class="item"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-with-grow.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-with-grow.html
new file mode 100644
index 0000000..8953fc7
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical-with-grow.html
@@ -0,0 +1,48 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: flex row with grow, vertical-rl</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="flex-row-vertical-with-grow-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#flexer {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+  width: 200px;
+  height: 200px;
+  background: lightgreen;
+  writing-mode: vertical-rl;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  flex-grow: 3;
+}
+.item {
+  width: 50px;
+  height: 60px;
+  background: blue;
+  flex-grow: 1;
+}
+</style>
+
+<div id="flexer">
+  <div class="item"></div>
+  <div id="container"></div>
+  <div class="item"></div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical.html
new file mode 100644
index 0000000..53f7571
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/flex-row-vertical.html
@@ -0,0 +1,46 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: flex row, vertical-rl</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="flex-row-vertical-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#flexer {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+  width: 200px;
+  height: 200px;
+  background: lightgreen;
+  writing-mode: vertical-rl;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+}
+.item {
+  width: 50px;
+  height: 60px;
+  background: blue;
+}
+</style>
+
+<div id="flexer">
+  <div class="item"></div>
+  <div id="container"></div>
+  <div class="item"></div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/float-left-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/float-left-ref.html
new file mode 100644
index 0000000..3ace1ee8
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/float-left-ref.html
@@ -0,0 +1,29 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: float left (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  float: left;
+}
+#sizer {
+  width: 123px;
+  height: 456px;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="sizer"></div>
+  </div>
+  This is some text.
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/float-left.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/float-left.html
new file mode 100644
index 0000000..7b8c642a
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/float-left.html
@@ -0,0 +1,43 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: float left</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="float-left-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  float: left;
+}
+#child {
+  width: 500px;
+  height: 500px;
+  background: red;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="child"></div>
+  </div>
+  This is some text.
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/layout-replaced-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/layout-replaced-ref.html
new file mode 100644
index 0000000..581031b
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/layout-replaced-ref.html
@@ -0,0 +1,24 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: layout replaced (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  border: 1px solid blue;
+  width: max-content;
+}
+img {
+  contain: style layout;
+  width: 12px;
+  height: 34px;
+  visibility: hidden;
+}
+</style>
+
+<div id="border">
+  <img src="resources/blue-100.png">
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/layout-replaced.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/layout-replaced.html
new file mode 100644
index 0000000..c2ef7627
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/layout-replaced.html
@@ -0,0 +1,33 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: layout replaced</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="layout-replaced-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  border: 1px solid blue;
+  width: max-content;
+}
+img {
+  contain: style layout;
+}
+</style>
+
+<div id="border">
+  <img id="element" src="resources/blue-100.png">
+</div>
+
+<script>
+async function runTest() {
+  const element = document.getElementById("element");
+  await element.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+window.onload = () => requestAnimationFrame(runTest);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/max-content-size-ignored-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/max-content-size-ignored-ref.html
new file mode 100644
index 0000000..025741f5
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/max-content-size-ignored-ref.html
@@ -0,0 +1,27 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: max-content on locked root ignored (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+}
+#sizer {
+  width: 123px;
+  height: 456px;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="sizer"></div>
+  </div>
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/max-content-size-ignored.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/max-content-size-ignored.html
new file mode 100644
index 0000000..68e967f36
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/max-content-size-ignored.html
@@ -0,0 +1,42 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: max-content on locked root ignored</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="max-content-size-ignored-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  width: max-content;
+}
+#child {
+  width: 500px;
+  height: 500px;
+  background: red;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="child"></div>
+  </div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/min-width-respected-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/min-width-respected-ref.html
new file mode 100644
index 0000000..4f4d824
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/min-width-respected-ref.html
@@ -0,0 +1,28 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: min-width on locked root respected (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  width: 157px;
+}
+#sizer {
+  width: 123px;
+  height: 456px;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="sizer"></div>
+  </div>
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/min-width-respected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/min-width-respected.html
new file mode 100644
index 0000000..6248843
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/min-width-respected.html
@@ -0,0 +1,42 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: min-width on locked root respected</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="min-width-respected-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  width: max-content;
+  border: 1px solid green;
+}
+#container {
+  contain: style layout;
+  background: lightblue;
+  min-width: 157px;
+}
+#child {
+  width: 500px;
+  height: 500px;
+  background: red;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div id="child"></div>
+  </div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] });
+  takeScreenshot();
+}
+
+window.onload = runTest;
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/overflow-auto-with-overflow-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/overflow-auto-with-overflow-ref.html
new file mode 100644
index 0000000..7c36f82
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/overflow-auto-with-overflow-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf8">
+<title>Display Locking: overflow auto (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<style>
+#border {
+  border: 1px solid black;
+  width: max-content;
+}
+#container {
+  contain: style layout;
+  width: 12px;
+  height: 100px;
+}
+</style>
+
+<div id="border">
+  <div id="container"></div>
+</div>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/overflow-auto-with-overflow.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/overflow-auto-with-overflow.html
new file mode 100644
index 0000000..d98b251
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/overflow-auto-with-overflow.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: overflow auto</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="overflow-auto-with-overflow-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+#border {
+  border: 1px solid black;
+  width: max-content;
+}
+#container {
+  contain: style layout;
+  height: 100px;
+  overflow: auto;
+}
+.content {
+  width: 50px;
+  height: 50px;
+  margin: 5px;
+  background: pink;
+}
+</style>
+
+<div id="border">
+  <div id="container">
+    <div class="content"></div>
+    <div class="content"></div>
+    <div class="content"></div>
+    <div class="content"></div>
+  </div>
+</div>
+
+<script>
+async function runTest() {
+  const container = document.getElementById("container");
+  await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] });
+  takeScreenshot();
+}
+
+onload = () => requestAnimationFrame(runTest);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/sizing/resources/blue-100.png b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/resources/blue-100.png
new file mode 100644
index 0000000..f578ae72
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/resources/blue-100.png
Binary files differ
diff --git a/third_party/blink/web_tests/display-lock/sizing/writing-modes-inherited-after-append.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-inherited-after-append.html
similarity index 76%
rename from third_party/blink/web_tests/display-lock/sizing/writing-modes-inherited-after-append.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-inherited-after-append.html
index b4f36199..4afc1a18 100644
--- a/third_party/blink/web_tests/display-lock/sizing/writing-modes-inherited-after-append.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-inherited-after-append.html
@@ -1,4 +1,12 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: writing modes change when appending</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="writing-modes-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
 <style>
 .verticalrl {
   writing-mode: vertical-rl;
@@ -40,15 +48,6 @@
 <div class="border horizontaltb"></div>
 
 <script>
-
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
 async function runTest() {
   let items = document.getElementsByClassName("border");
   let template_element = document.importNode(
@@ -61,9 +60,9 @@
     items[i].appendChild(clone);
   }
   await Promise.all(promises);
-  finishTest();
+  takeScreenshot();
 }
 
 onload = () => requestAnimationFrame(runTest);
 </script>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/writing-modes-expected.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-ref.html
similarity index 69%
rename from third_party/blink/web_tests/display-lock/sizing/writing-modes-expected.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-ref.html
index 2ca5e8f0..4b3da48 100644
--- a/third_party/blink/web_tests/display-lock/sizing/writing-modes-expected.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-ref.html
@@ -1,4 +1,10 @@
 <!DOCTYPE html>
+<html>
+<meta charset="utf8">
+<title>Display Locking: writing modes (reference)</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
 <style>
 .sized {
   width: 12px;
@@ -30,4 +36,4 @@
 <div class="border">
     <div class="sized"></div>
 </div>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/writing-modes-switch.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-switch.html
similarity index 82%
rename from third_party/blink/web_tests/display-lock/sizing/writing-modes-switch.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-switch.html
index 76f58ea..158063b 100644
--- a/third_party/blink/web_tests/display-lock/sizing/writing-modes-switch.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes-switch.html
@@ -1,4 +1,12 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: writing modes switch</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="writing-modes-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
 <style>
 .verticalrl {
   writing-mode: vertical-rl;
@@ -54,15 +62,6 @@
 </div>
 
 <script>
-
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
 async function runTest() {
   let items = document.getElementsByClassName("box");
   let promises = []
@@ -81,9 +80,9 @@
     }
   }
 
-  requestAnimationFrame(finishTest);
+  takeScreenshot();
 }
 
 onload = () => requestAnimationFrame(runTest);
 </script>
-
+</html>
diff --git a/third_party/blink/web_tests/display-lock/sizing/writing-modes.html b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes.html
similarity index 74%
rename from third_party/blink/web_tests/display-lock/sizing/writing-modes.html
rename to third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes.html
index c175ffa..51523903 100644
--- a/third_party/blink/web_tests/display-lock/sizing/writing-modes.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/sizing/writing-modes.html
@@ -1,4 +1,12 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Display Locking: writing modes</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<link rel="match" href="writing-modes-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
 <style>
 .verticalrl {
   writing-mode: vertical-rl;
@@ -54,25 +62,16 @@
 </div>
 
 <script>
-
-if (window.testRunner)
-  window.testRunner.waitUntilDone();
-
-function finishTest() {
-  if (window.testRunner)
-    window.testRunner.notifyDone();
-}
-
 async function runTest() {
-  let items = document.getElementsByClassName("box");
-  let promises = []
+  const items = document.getElementsByClassName("box");
+  const promises = []
   for (let i = 0; i < items.length; ++i) {
     promises.push(items[i].displayLock.acquire({ timeout: Infinity, size: [12, 34] }));
   }
   await Promise.all(promises);
-  finishTest();
+  takeScreenshot();
 }
 
 onload = () => requestAnimationFrame(runTest);
 </script>
-
+</html>
diff --git a/third_party/libaddressinput/chromium/input_suggester.cc b/third_party/libaddressinput/chromium/input_suggester.cc
index 9b890f111..8ce386c 100644
--- a/third_party/libaddressinput/chromium/input_suggester.cc
+++ b/third_party/libaddressinput/chromium/input_suggester.cc
@@ -228,8 +228,25 @@
   UErrorCode error_code = U_ZERO_ERROR;
   collator_.reset(
       icu::Collator::createInstance(icu::Locale::getRoot(), error_code));
+  if (!collator_ || !U_SUCCESS(error_code)) {
+    // On some systems, the default locale is invalid to the eyes of the ICU
+    // library. This could be due to a device-specific issue (has been seen in
+    // the wild on Android and iOS devices). In the failure case, |collator_|
+    // will be null. See http://crbug.com/558625.
+
+    // Attempt to load the English locale.
+    error_code = U_ZERO_ERROR;
+    collator_.reset(
+        icu::Collator::createInstance(icu::Locale::getEnglish(), error_code));
+    if (!collator_) {
+      LOG(ERROR) << "Failed to initialize the ICU Collator with the English "
+                 << "locale.";
+    }
+  }
+
   DCHECK(U_SUCCESS(error_code));
-  collator_->setStrength(icu::Collator::PRIMARY);
+  if (collator_ && U_SUCCESS(error_code))
+    collator_->setStrength(icu::Collator::PRIMARY);
 }
 
 InputSuggester::StringCanonicalizer::~StringCanonicalizer() {}
@@ -240,8 +257,9 @@
 
   icu::UnicodeString icu_str(original.c_str(),
                              static_cast<int32_t>(original.length()));
-  int32_t sort_key_size =
-      collator_->getSortKey(icu_str, &buffer_[0], buffer_size());
+  int32_t sort_key_size = 0;
+  if (collator_)
+    collator_->getSortKey(icu_str, &buffer_[0], buffer_size());
   DCHECK_LT(0, sort_key_size);
 
   if (sort_key_size > buffer_size()) {
diff --git a/third_party/libcxx-pretty-printers/README.chromium b/third_party/libcxx-pretty-printers/README.chromium
index b65151b9..332511d 100644
--- a/third_party/libcxx-pretty-printers/README.chromium
+++ b/third_party/libcxx-pretty-printers/README.chromium
@@ -1,6 +1,6 @@
 Name: libcxx-pretty-printers
 URL: https://github.com/koutheir/libcxx-pretty-printers
-Version: b04941d7f9fbc29d2a2e1c56af765001eebc61e3
+Version: 5c40997ea6850a11321907b4651954bcfa6a21c7
 License: GPL v3
 License File: LICENSE
 Security Critical: no
diff --git a/third_party/libcxx-pretty-printers/printers.py b/third_party/libcxx-pretty-printers/printers.py
index 2d7e086..7f06a759d 100644
--- a/third_party/libcxx-pretty-printers/printers.py
+++ b/third_party/libcxx-pretty-printers/printers.py
@@ -148,7 +148,7 @@
             len = sl['__size_']
             ptr = sl['__data_']
 
-        return ptr.string(length=len)
+        return ''.join(chr(ptr[i]) for i in range(len))
 
     def display_hint(self):
         return 'string'
diff --git a/third_party/pffft/BUILD.gn b/third_party/pffft/BUILD.gn
index ed20e32..17b85b5 100644
--- a/third_party/pffft/BUILD.gn
+++ b/third_party/pffft/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/arm.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
 import("//testing/test.gni")
 
@@ -12,6 +13,9 @@
       "_USE_MATH_DEFINES",
     ]
   }
+  if (current_cpu == "arm" && !arm_use_neon) {
+    defines = [ "PFFFT_SIMD_DISABLE" ]
+  }
 }
 
 static_library("pffft") {
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py
new file mode 100755
index 0000000..a666403
--- /dev/null
+++ b/tools/clang/scripts/build.py
@@ -0,0 +1,790 @@
+#!/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.
+
+"""This script is used to build clang binaries. It is used by package.py to
+create the prebuilt binaries downloaded by update.py and used by developers.
+
+The expectation is that update.py downloads prebuilt binaries for everyone, and
+nobody should run this script as part of normal development.
+"""
+
+from __future__ import print_function
+
+import argparse
+import glob
+import os
+import pipes
+import re
+import shutil
+import subprocess
+import sys
+
+from update import (CDS_URL, CHROMIUM_DIR, CLANG_REVISION, LLVM_BUILD_DIR,
+                    FORCE_HEAD_REVISION_FILE, PACKAGE_VERSION, RELEASE_VERSION,
+                    STAMP_FILE, CopyFile, CopyDiaDllTo, DownloadAndUnpack,
+                    EnsureDirExists, GetWinSDKDir, ReadStampFile, RmTree,
+                    WriteStampFile)
+
+
+# Path constants. (All of these should be absolute paths.)
+THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party')
+LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm')
+LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap')
+LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
+                                          'llvm-bootstrap-install')
+CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
+THREADS_ENABLED_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, 'threads_enabled')
+COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, 'compiler-rt')
+CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
+LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
+# compiler-rt is built as part of the regular LLVM build on Windows to get
+# the 64-bit runtime, and out-of-tree elsewhere.
+# TODO(thakis): Try to unify this.
+if sys.platform == 'win32':
+  COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
+else:
+  COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'compiler-rt')
+LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx')
+LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi')
+LLVM_BUILD_TOOLS_DIR = os.path.abspath(
+    os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
+ANDROID_NDK_DIR = os.path.join(
+    CHROMIUM_DIR, 'third_party', 'android_ndk')
+FUCHSIA_SDK_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'fuchsia-sdk',
+                               'sdk')
+
+LLVM_REPO_URL = os.environ.get('LLVM_REPO_URL',
+                               'https://llvm.org/svn/llvm-project')
+
+BUG_REPORT_URL = ('https://crbug.com and run tools/clang/scripts/upload_crash.py'
+                  ' (only works inside Google) which will upload a report')
+
+
+def GetSvnRevision(svn_repo):
+  """Returns current revision of the svn repo at svn_repo."""
+  svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True)
+  m = re.search(r'Revision: (\d+)', svn_info)
+  return m.group(1)
+
+
+def RmCmakeCache(dir):
+  """Delete CMake cache related files from dir."""
+  for dirpath, dirs, files in os.walk(dir):
+    if 'CMakeCache.txt' in files:
+      os.remove(os.path.join(dirpath, 'CMakeCache.txt'))
+    if 'CMakeFiles' in dirs:
+      RmTree(os.path.join(dirpath, 'CMakeFiles'))
+
+
+def RunCommand(command, msvc_arch=None, env=None, fail_hard=True):
+  """Run command and return success (True) or failure; or if fail_hard is
+     True, exit on failure.  If msvc_arch is set, runs the command in a
+     shell with the msvc tools for that architecture."""
+
+  if msvc_arch and sys.platform == 'win32':
+    command = [os.path.join(GetWinSDKDir(), 'bin', 'SetEnv.cmd'),
+               "/" + msvc_arch, '&&'] + command
+
+  # https://docs.python.org/2/library/subprocess.html:
+  # "On Unix with shell=True [...] if args is a sequence, the first item
+  # specifies the command string, and any additional items will be treated as
+  # additional arguments to the shell itself.  That is to say, Popen does the
+  # equivalent of:
+  #   Popen(['/bin/sh', '-c', args[0], args[1], ...])"
+  #
+  # We want to pass additional arguments to command[0], not to the shell,
+  # so manually join everything into a single string.
+  # Annoyingly, for "svn co url c:\path", pipes.quote() thinks that it should
+  # quote c:\path but svn can't handle quoted paths on Windows.  Since on
+  # Windows follow-on args are passed to args[0] instead of the shell, don't
+  # do the single-string transformation there.
+  if sys.platform != 'win32':
+    command = ' '.join([pipes.quote(c) for c in command])
+  print('Running', command)
+  if subprocess.call(command, env=env, shell=True) == 0:
+    return True
+  print('Failed.')
+  if fail_hard:
+    sys.exit(1)
+  return False
+
+
+def CopyDirectoryContents(src, dst):
+  """Copy the files from directory src to dst."""
+  dst = os.path.realpath(dst)  # realpath() in case dst ends in /..
+  EnsureDirExists(dst)
+  for f in os.listdir(src):
+    CopyFile(os.path.join(src, f), dst)
+
+
+def Checkout(name, url, dir):
+  """Checkout the SVN module at url into dir. Use name for the log message."""
+  print("Checking out %s r%s into '%s'" % (name, CLANG_REVISION, dir))
+
+  command = ['svn', 'checkout', '--force', url + '@' + CLANG_REVISION, dir]
+  if RunCommand(command, fail_hard=False):
+    return
+
+  if os.path.isdir(dir):
+    print("Removing %s." % dir)
+    RmTree(dir)
+
+  print("Retrying.")
+  RunCommand(command)
+
+
+def CheckoutRepos(args):
+  if args.skip_checkout:
+    return
+
+  Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
+  Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
+  if True:
+    Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
+  elif os.path.exists(LLD_DIR):
+    # In case someone sends a tryjob that temporary adds lld to the checkout,
+    # make sure it's not around on future builds.
+    RmTree(LLD_DIR)
+  Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
+  if sys.platform == 'darwin':
+    # clang needs a libc++ checkout, else -stdlib=libc++ won't find includes
+    # (i.e. this is needed for bootstrap builds).
+    Checkout('libcxx', LLVM_REPO_URL + '/libcxx/trunk', LIBCXX_DIR)
+    # We used to check out libcxxabi on OS X; we no longer need that.
+    if os.path.exists(LIBCXXABI_DIR):
+      RmTree(LIBCXXABI_DIR)
+
+
+def DeleteChromeToolsShim():
+  OLD_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'zzz-chrometools')
+  shutil.rmtree(OLD_SHIM_DIR, ignore_errors=True)
+  shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True)
+
+
+def CreateChromeToolsShim():
+  """Hooks the Chrome tools into the LLVM build.
+
+  Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build
+  detects implicit tools in the tools subdirectory, so this helper install a
+  shim CMakeLists.txt that forwards to the real directory for the Chrome tools.
+
+  Note that the shim directory name intentionally has no - or _. The implicit
+  tool detection logic munges them in a weird way."""
+  assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_')
+  os.mkdir(CHROME_TOOLS_SHIM_DIR)
+  with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f:
+    f.write('# Automatically generated by tools/clang/scripts/update.py. ' +
+            'Do not edit.\n')
+    f.write('# Since tools/clang is located in another directory, use the \n')
+    f.write('# two arg version to specify where build artifacts go. CMake\n')
+    f.write('# disallows reuse of the same binary dir for multiple source\n')
+    f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
+    f.write('if (CHROMIUM_TOOLS_SRC)\n')
+    f.write('  add_subdirectory(${CHROMIUM_TOOLS_SRC} ' +
+              '${CMAKE_CURRENT_BINARY_DIR}/a)\n')
+    f.write('endif (CHROMIUM_TOOLS_SRC)\n')
+
+
+def AddSvnToPathOnWin():
+  """Download svn.exe and add it to PATH."""
+  if sys.platform != 'win32':
+    return
+  svn_ver = 'svn-1.6.6-win'
+  svn_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, svn_ver)
+  if not os.path.exists(svn_dir):
+    DownloadAndUnpack(CDS_URL + '/tools/%s.zip' % svn_ver, LLVM_BUILD_TOOLS_DIR)
+  os.environ['PATH'] = svn_dir + os.pathsep + os.environ.get('PATH', '')
+
+
+def AddCMakeToPath(args):
+  """Download CMake and add it to PATH."""
+  if args.use_system_cmake:
+    return
+
+  if sys.platform == 'win32':
+    zip_name = 'cmake-3.12.1-win32-x86.zip'
+    dir_name = ['cmake-3.12.1-win32-x86', 'bin']
+  elif sys.platform == 'darwin':
+    zip_name = 'cmake-3.12.1-Darwin-x86_64.tar.gz'
+    dir_name = ['cmake-3.12.1-Darwin-x86_64', 'CMake.app', 'Contents', 'bin']
+  else:
+    zip_name = 'cmake-3.12.1-Linux-x86_64.tar.gz'
+    dir_name = ['cmake-3.12.1-Linux-x86_64', 'bin']
+
+  cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, *dir_name)
+  if not os.path.exists(cmake_dir):
+    DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
+  os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
+
+
+def AddGnuWinToPath():
+  """Download some GNU win tools and add them to PATH."""
+  if sys.platform != 'win32':
+    return
+
+  gnuwin_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gnuwin')
+  GNUWIN_VERSION = '9'
+  GNUWIN_STAMP = os.path.join(gnuwin_dir, 'stamp')
+  if ReadStampFile(GNUWIN_STAMP) == GNUWIN_VERSION:
+    print('GNU Win tools already up to date.')
+  else:
+    zip_name = 'gnuwin-%s.zip' % GNUWIN_VERSION
+    DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
+    WriteStampFile(GNUWIN_VERSION, GNUWIN_STAMP)
+
+  os.environ['PATH'] = gnuwin_dir + os.pathsep + os.environ.get('PATH', '')
+
+  # find.exe, mv.exe and rm.exe are from MSYS (see crrev.com/389632). MSYS uses
+  # Cygwin under the hood, and initializing Cygwin has a race-condition when
+  # getting group and user data from the Active Directory is slow. To work
+  # around this, use a horrible hack telling it not to do that.
+  # See https://crbug.com/905289
+  etc = os.path.join(gnuwin_dir, '..', '..', 'etc')
+  EnsureDirExists(etc)
+  with open(os.path.join(etc, 'nsswitch.conf'), 'w') as f:
+    f.write('passwd: files\n')
+    f.write('group: files\n')
+
+
+def SetMacXcodePath():
+  """Set DEVELOPER_DIR to the path to hermetic Xcode.app on Mac OS X."""
+  if sys.platform != 'darwin':
+    return
+
+  xcode_path = os.path.join(CHROMIUM_DIR, 'build', 'mac_files', 'Xcode.app')
+  if os.path.exists(xcode_path):
+    os.environ['DEVELOPER_DIR'] = xcode_path
+
+
+def VerifyVersionOfBuiltClangMatchesVERSION():
+  """Checks that `clang --version` outputs RELEASE_VERSION. If this
+  fails, update.RELEASE_VERSION is out-of-date and needs to be updated (possibly
+  in an `if args.llvm_force_head_revision:` block inupdate. main() first)."""
+  clang = os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')
+  if sys.platform == 'win32':
+    # TODO: Parse `clang-cl /?` output for built clang's version and check that
+    # to check the binary we're actually shipping? But clang-cl.exe is just
+    # a copy of clang.exe, so this does check the same thing.
+    clang += '.exe'
+  version_out = subprocess.check_output([clang, '--version'])
+  version_out = re.match(r'clang version ([0-9.]+)', version_out).group(1)
+  if version_out != RELEASE_VERSION:
+    print(('unexpected clang version %s (not %s), '
+           'update RELEASE_VERSION in update.py')
+          % (version_out, RELEASE_VERSION))
+    sys.exit(1)
+
+
+def gn_arg(v):
+  if v == 'True':
+    return True
+  if v == 'False':
+    return False
+  raise argparse.ArgumentTypeError('Expected one of %r or %r' % (
+      'True', 'False'))
+
+
+def main():
+  parser = argparse.ArgumentParser(description='Build Clang.')
+  parser.add_argument('--bootstrap', action='store_true',
+                      help='first build clang with CC, then with itself.')
+  parser.add_argument('--disable-asserts', action='store_true',
+                      help='build with asserts disabled')
+  parser.add_argument('--gcc-toolchain', help='(no longer used)')
+  parser.add_argument('--lto-lld', action='store_true',
+                      help='build lld with LTO')
+  parser.add_argument('--llvm-force-head-revision', action='store_true',
+                      help='build the latest revision')
+  parser.add_argument('--run-tests', action='store_true',
+                      help='run tests after building')
+  parser.add_argument('--skip-build', action='store_true',
+                      help='do not build anything')
+  parser.add_argument('--skip-checkout', action='store_true',
+                      help='do not create or update any checkouts')
+  parser.add_argument('--extra-tools', nargs='*', default=[],
+                      help='select additional chrome tools to build')
+  parser.add_argument('--use-system-cmake', action='store_true',
+                      help='use the cmake from PATH instead of downloading '
+                      'and using prebuilt cmake binaries')
+  parser.add_argument('--with-android', type=gn_arg, nargs='?', const=True,
+                      help='build the Android ASan runtime (linux only)',
+                      default=sys.platform.startswith('linux'))
+  parser.add_argument('--without-android', action='store_false',
+                      help='don\'t build Android ASan runtime (linux only)',
+                      dest='with_android')
+  parser.add_argument('--without-fuchsia', action='store_false',
+                      help='don\'t build Fuchsia clang_rt runtime (linux/mac)',
+                      dest='with_fuchsia',
+                      default=sys.platform in ('linux2', 'darwin'))
+  args = parser.parse_args()
+
+  if args.lto_lld and not args.bootstrap:
+    print('--lto-lld requires --bootstrap')
+    return 1
+  if args.lto_lld and not sys.platform.startswith('linux'):
+    print('--lto-lld is only effective on Linux. Ignoring the option.')
+    args.lto_lld = False
+  if args.with_android and not os.path.exists(ANDROID_NDK_DIR):
+    print('Android NDK not found at ' + ANDROID_NDK_DIR)
+    print('The Android NDK is needed to build a Clang whose -fsanitize=address')
+    print('works on Android. See ')
+    print('https://www.chromium.org/developers/how-tos/android-build-instructions')
+    print('for how to install the NDK, or pass --without-android.')
+    return 1
+
+  if args.llvm_force_head_revision:
+    # Always run tests for ToT builds.
+    args.run_tests = True
+    # Don't build fuchsia runtime on ToT bots at all.
+    args.with_fuchsia = False
+
+  if args.with_fuchsia and not os.path.exists(FUCHSIA_SDK_DIR):
+    print('Fuchsia SDK not found at ' + FUCHSIA_SDK_DIR)
+    print('The Fuchsia SDK is needed to build libclang_rt for Fuchsia.')
+    print('Install the Fuchsia SDK by adding fuchsia to the ')
+    print('target_os section in your .gclient and running hooks, ')
+    print('or pass --without-fuchsia.')
+    print('https://chromium.googlesource.com/chromium/src/+/master/docs/fuchsia_build_instructions.md')
+    print('for general Fuchsia build instructions.')
+    return 1
+
+
+  # DEVELOPER_DIR needs to be set when Xcode isn't in a standard location
+  # and xcode-select wasn't run.  This is needed for running clang and ld
+  # for the build done by this script, but it's also needed for running
+  # macOS system svn, so this needs to happen before calling functions using
+  # svn.
+  SetMacXcodePath()
+
+  AddSvnToPathOnWin()
+
+  global CLANG_REVISION, PACKAGE_VERSION
+  if args.llvm_force_head_revision:
+    CLANG_REVISION = GetSvnRevision(LLVM_REPO_URL)
+    PACKAGE_VERSION = CLANG_REVISION + '-0'
+
+  # Don't buffer stdout, so that print statements are immediately flushed.
+  sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
+
+  print('Locally building clang %s...' % PACKAGE_VERSION)
+  WriteStampFile('', STAMP_FILE)
+  WriteStampFile('', FORCE_HEAD_REVISION_FILE)
+
+  AddCMakeToPath(args)
+  AddGnuWinToPath()
+
+  DeleteChromeToolsShim()
+
+  CheckoutRepos(args)
+
+  if args.skip_build:
+    return
+
+  cc, cxx = None, None
+
+  cflags = []
+  cxxflags = []
+  ldflags = []
+
+  targets = 'AArch64;ARM;Mips;PowerPC;SystemZ;WebAssembly;X86'
+  base_cmake_args = ['-GNinja',
+                     '-DCMAKE_BUILD_TYPE=Release',
+                     '-DLLVM_ENABLE_ASSERTIONS=%s' %
+                         ('OFF' if args.disable_asserts else 'ON'),
+                     '-DLLVM_ENABLE_PIC=OFF',
+                     '-DLLVM_ENABLE_TERMINFO=OFF',
+                     '-DLLVM_TARGETS_TO_BUILD=' + targets,
+                     # Statically link MSVCRT to avoid DLL dependencies.
+                     '-DLLVM_USE_CRT_RELEASE=MT',
+                     '-DCLANG_PLUGIN_SUPPORT=OFF',
+                     '-DCLANG_ENABLE_STATIC_ANALYZER=OFF',
+                     '-DCLANG_ENABLE_ARCMT=OFF',
+                     # TODO(crbug.com/929645): Use newer toolchain to host.
+                     '-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON',
+                     '-DBUG_REPORT_URL=' + BUG_REPORT_URL,
+                     ]
+
+  if sys.platform != 'win32':
+    # libxml2 is required by the Win manifest merging tool used in cross-builds.
+    base_cmake_args.append('-DLLVM_ENABLE_LIBXML2=FORCE_ON')
+
+  if args.bootstrap:
+    print('Building bootstrap compiler')
+    EnsureDirExists(LLVM_BOOTSTRAP_DIR)
+    os.chdir(LLVM_BOOTSTRAP_DIR)
+    bootstrap_args = base_cmake_args + [
+        '-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64',
+        '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR,
+        '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+        '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
+        # Ignore args.disable_asserts for the bootstrap compiler.
+        '-DLLVM_ENABLE_ASSERTIONS=ON',
+        ]
+    if cc is not None:  bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc)
+    if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
+    RmCmakeCache('.')
+    RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64')
+    RunCommand(['ninja'], msvc_arch='x64')
+    if args.run_tests:
+      if sys.platform == 'win32':
+        CopyDiaDllTo(os.path.join(LLVM_BOOTSTRAP_DIR, 'bin'))
+      RunCommand(['ninja', 'check-all'], msvc_arch='x64')
+    RunCommand(['ninja', 'install'], msvc_arch='x64')
+
+    if sys.platform == 'win32':
+      cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
+      cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
+      # CMake has a hard time with backslashes in compiler paths:
+      # https://stackoverflow.com/questions/13050827
+      cc = cc.replace('\\', '/')
+      cxx = cxx.replace('\\', '/')
+    else:
+      cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang')
+      cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang++')
+
+    print('Building final compiler')
+
+  # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is
+  # needed, on OS X it requires libc++. clang only automatically links to libc++
+  # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run
+  # on OS X versions as old as 10.7.
+  deployment_target = ''
+
+  if sys.platform == 'darwin' and args.bootstrap:
+    # When building on 10.9, /usr/include usually doesn't exist, and while
+    # Xcode's clang automatically sets a sysroot, self-built clangs don't.
+    cflags = ['-isysroot', subprocess.check_output(
+        ['xcrun', '--show-sdk-path']).rstrip()]
+    cxxflags = ['-stdlib=libc++'] + cflags
+    ldflags += ['-stdlib=libc++']
+    deployment_target = '10.7'
+    # Running libc++ tests takes a long time. Since it was only needed for
+    # the install step above, don't build it as part of the main build.
+    # This makes running package.py over 10% faster (30 min instead of 34 min)
+    RmTree(LIBCXX_DIR)
+
+
+  # If building at head, define a macro that plugins can use for #ifdefing
+  # out code that builds at head, but not at CLANG_REVISION or vice versa.
+  if args.llvm_force_head_revision:
+    cflags += ['-DLLVM_FORCE_HEAD_REVISION']
+    cxxflags += ['-DLLVM_FORCE_HEAD_REVISION']
+
+  # Build PDBs for archival on Windows.  Don't use RelWithDebInfo since it
+  # has different optimization defaults than Release.
+  # Also disable stack cookies (/GS-) for performance.
+  if sys.platform == 'win32':
+    cflags += ['/Zi', '/GS-']
+    cxxflags += ['/Zi', '/GS-']
+    ldflags += ['/DEBUG', '/OPT:REF', '/OPT:ICF']
+
+  deployment_env = None
+  if deployment_target:
+    deployment_env = os.environ.copy()
+    deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
+
+  # Build lld and code coverage tools. This is done separately from the rest of
+  # the build because these tools require threading support.
+  tools_with_threading = [ 'dsymutil', 'lld', 'llvm-cov', 'llvm-profdata' ]
+  print('Building the following tools with threading support: %s' %
+        str(tools_with_threading))
+
+  if os.path.exists(THREADS_ENABLED_BUILD_DIR):
+    RmTree(THREADS_ENABLED_BUILD_DIR)
+  EnsureDirExists(THREADS_ENABLED_BUILD_DIR)
+  os.chdir(THREADS_ENABLED_BUILD_DIR)
+
+  threads_enabled_cmake_args = base_cmake_args + [
+      '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+      '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
+      '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
+      '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
+      '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags)]
+  if cc is not None:
+    threads_enabled_cmake_args.append('-DCMAKE_C_COMPILER=' + cc)
+  if cxx is not None:
+    threads_enabled_cmake_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
+
+  if args.lto_lld:
+    # Build lld with LTO. That speeds up the linker by ~10%.
+    # We only use LTO for Linux now.
+    #
+    # The linker expects all archive members to have symbol tables, so the
+    # archiver needs to be able to create symbol tables for bitcode files.
+    # GNU ar and ranlib don't understand bitcode files, but llvm-ar and
+    # llvm-ranlib do, so use them.
+    ar = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'llvm-ar')
+    ranlib = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'llvm-ranlib')
+    threads_enabled_cmake_args += [
+        '-DCMAKE_AR=' + ar,
+        '-DCMAKE_RANLIB=' + ranlib,
+        '-DLLVM_ENABLE_LTO=thin',
+        '-DLLVM_USE_LINKER=lld']
+
+  RmCmakeCache('.')
+  RunCommand(['cmake'] + threads_enabled_cmake_args + [LLVM_DIR],
+             msvc_arch='x64', env=deployment_env)
+  RunCommand(['ninja'] + tools_with_threading, msvc_arch='x64')
+
+  # Build clang and other tools.
+  CreateChromeToolsShim()
+
+  cmake_args = []
+  # TODO(thakis): Unconditionally append this to base_cmake_args instead once
+  # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
+  cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
+  if cc is not None:  cc_args.append('-DCMAKE_C_COMPILER=' + cc)
+  if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
+  default_tools = ['plugins', 'blink_gc_plugin', 'translation_unit']
+  chrome_tools = list(set(default_tools + args.extra_tools))
+  cmake_args += base_cmake_args + [
+      '-DLLVM_ENABLE_THREADS=OFF',
+      '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+      '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
+      '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
+      '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
+      '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags),
+      '-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR,
+      '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
+      '-DCHROMIUM_TOOLS=%s' % ';'.join(chrome_tools)]
+
+  EnsureDirExists(LLVM_BUILD_DIR)
+  os.chdir(LLVM_BUILD_DIR)
+  RmCmakeCache('.')
+  RunCommand(['cmake'] + cmake_args + [LLVM_DIR],
+             msvc_arch='x64', env=deployment_env)
+  RunCommand(['ninja'], msvc_arch='x64')
+
+  # Copy in the threaded versions of lld and other tools.
+  if sys.platform == 'win32':
+    CopyFile(os.path.join(THREADS_ENABLED_BUILD_DIR, 'bin', 'lld-link.exe'),
+             os.path.join(LLVM_BUILD_DIR, 'bin'))
+    CopyFile(os.path.join(THREADS_ENABLED_BUILD_DIR, 'bin', 'lld.pdb'),
+             os.path.join(LLVM_BUILD_DIR, 'bin'))
+  else:
+    for tool in tools_with_threading:
+      CopyFile(os.path.join(THREADS_ENABLED_BUILD_DIR, 'bin', tool),
+               os.path.join(LLVM_BUILD_DIR, 'bin'))
+
+  if chrome_tools:
+    # If any Chromium tools were built, install those now.
+    RunCommand(['ninja', 'cr-install'], msvc_arch='x64')
+
+  VerifyVersionOfBuiltClangMatchesVERSION()
+
+  # Do an out-of-tree build of compiler-rt.
+  # On Windows, this is used to get the 32-bit ASan run-time.
+  # TODO(hans): Remove once the regular build above produces this.
+  # On Mac and Linux, this is used to get the regular 64-bit run-time.
+  # Do a clobbered build due to cmake changes.
+  if os.path.isdir(COMPILER_RT_BUILD_DIR):
+    RmTree(COMPILER_RT_BUILD_DIR)
+  os.makedirs(COMPILER_RT_BUILD_DIR)
+  os.chdir(COMPILER_RT_BUILD_DIR)
+  # TODO(thakis): Add this once compiler-rt can build with clang-cl (see
+  # above).
+  #if args.bootstrap and sys.platform == 'win32':
+    # The bootstrap compiler produces 64-bit binaries by default.
+    #cflags += ['-m32']
+    #cxxflags += ['-m32']
+  compiler_rt_args = base_cmake_args + [
+      '-DLLVM_ENABLE_THREADS=OFF',
+      '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+      '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)]
+  if sys.platform == 'darwin':
+    compiler_rt_args += ['-DCOMPILER_RT_ENABLE_IOS=ON']
+  if sys.platform != 'win32':
+    compiler_rt_args += ['-DLLVM_CONFIG_PATH=' +
+                         os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config'),
+                        '-DSANITIZER_MIN_OSX_VERSION="10.7"']
+  # compiler-rt is part of the llvm checkout on Windows but a stand-alone
+  # directory elsewhere, see the TODO above COMPILER_RT_DIR.
+  RmCmakeCache('.')
+  RunCommand(['cmake'] + compiler_rt_args +
+             [LLVM_DIR if sys.platform == 'win32' else COMPILER_RT_DIR],
+             msvc_arch='x86', env=deployment_env)
+  RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86')
+  if sys.platform != 'win32':
+    RunCommand(['ninja', 'fuzzer'])
+
+  # Copy select output to the main tree.
+  # TODO(hans): Make this (and the .gypi and .isolate files) version number
+  # independent.
+  if sys.platform == 'win32':
+    platform = 'windows'
+  elif sys.platform == 'darwin':
+    platform = 'darwin'
+  else:
+    assert sys.platform.startswith('linux')
+    platform = 'linux'
+  rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', platform)
+  if sys.platform == 'win32':
+    # TODO(thakis): This too is due to compiler-rt being part of the checkout
+    # on Windows, see TODO above COMPILER_RT_DIR.
+    rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
+                                  RELEASE_VERSION, 'lib', platform)
+  rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', RELEASE_VERSION,
+                                'lib', platform)
+  # Blacklists:
+  CopyDirectoryContents(os.path.join(rt_lib_src_dir, '..', '..', 'share'),
+                        os.path.join(rt_lib_dst_dir, '..', '..', 'share'))
+  # Headers:
+  if sys.platform != 'win32':
+    CopyDirectoryContents(
+        os.path.join(COMPILER_RT_BUILD_DIR, 'include/sanitizer'),
+        os.path.join(LLVM_BUILD_DIR, 'lib/clang', RELEASE_VERSION,
+                     'include/sanitizer'))
+  # Static and dynamic libraries:
+  CopyDirectoryContents(rt_lib_src_dir, rt_lib_dst_dir)
+  if sys.platform == 'darwin':
+    for dylib in glob.glob(os.path.join(rt_lib_dst_dir, '*.dylib')):
+      # Fix LC_ID_DYLIB for the ASan dynamic libraries to be relative to
+      # @executable_path.
+      # TODO(glider): this is transitional. We'll need to fix the dylib
+      # name either in our build system, or in Clang. See also
+      # http://crbug.com/344836.
+      subprocess.call(['install_name_tool', '-id',
+                       '@executable_path/' + os.path.basename(dylib), dylib])
+
+  if args.with_android:
+    make_toolchain = os.path.join(
+        ANDROID_NDK_DIR, 'build', 'tools', 'make_standalone_toolchain.py')
+    for target_arch in ['aarch64', 'arm', 'i686']:
+      # Make standalone Android toolchain for target_arch.
+      toolchain_dir = os.path.join(
+          LLVM_BUILD_DIR, 'android-toolchain-' + target_arch)
+      api_level = '21' if target_arch == 'aarch64' else '19'
+      RunCommand([
+          make_toolchain,
+          '--api=' + api_level,
+          '--force',
+          '--install-dir=%s' % toolchain_dir,
+          '--stl=libc++',
+          '--arch=' + {
+              'aarch64': 'arm64',
+              'arm': 'arm',
+              'i686': 'x86',
+          }[target_arch]])
+
+      # NDK r16 "helpfully" installs libc++ as libstdc++ "so the compiler will
+      # pick it up by default". Only these days, the compiler tries to find
+      # libc++ instead. See https://crbug.com/902270.
+      shutil.copy(os.path.join(toolchain_dir, 'sysroot/usr/lib/libstdc++.a'),
+                  os.path.join(toolchain_dir, 'sysroot/usr/lib/libc++.a'))
+      shutil.copy(os.path.join(toolchain_dir, 'sysroot/usr/lib/libstdc++.so'),
+                  os.path.join(toolchain_dir, 'sysroot/usr/lib/libc++.so'))
+
+      # Build compiler-rt runtimes needed for Android in a separate build tree.
+      build_dir = os.path.join(LLVM_BUILD_DIR, 'android-' + target_arch)
+      if not os.path.exists(build_dir):
+        os.mkdir(os.path.join(build_dir))
+      os.chdir(build_dir)
+      target_triple = target_arch
+      if target_arch == 'arm':
+        target_triple = 'armv7'
+      target_triple += '-linux-android' + api_level
+      cflags = ['--target=%s' % target_triple,
+                '--sysroot=%s/sysroot' % toolchain_dir,
+                '-B%s' % toolchain_dir]
+      android_args = base_cmake_args + [
+        '-DLLVM_ENABLE_THREADS=OFF',
+        '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
+        '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
+        '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
+        '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+        '-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
+        '-DCMAKE_ASM_FLAGS=' + ' '.join(cflags),
+        '-DSANITIZER_CXX_ABI=libcxxabi',
+        '-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-u__cxa_demangle',
+        '-DANDROID=1']
+      RmCmakeCache('.')
+      RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR])
+
+      # We use ASan i686 build for fuzzing.
+      libs_want = ['lib/linux/libclang_rt.asan-{0}-android.so']
+      if target_arch in ['aarch64', 'arm']:
+        libs_want += [
+            'lib/linux/libclang_rt.ubsan_standalone-{0}-android.so',
+            'lib/linux/libclang_rt.profile-{0}-android.a',
+        ]
+      if target_arch == 'aarch64':
+        libs_want += ['lib/linux/libclang_rt.hwasan-{0}-android.so']
+      libs_want = [lib.format(target_arch) for lib in libs_want]
+      RunCommand(['ninja'] + libs_want)
+
+      # And copy them into the main build tree.
+      for p in libs_want:
+        shutil.copy(p, rt_lib_dst_dir)
+
+  if args.with_fuchsia:
+    # Fuchsia links against libclang_rt.builtins-<arch>.a instead of libgcc.a.
+    for target_arch in ['aarch64', 'x86_64']:
+      fuchsia_arch_name = {'aarch64': 'arm64', 'x86_64': 'x64'}[target_arch]
+      toolchain_dir = os.path.join(
+          FUCHSIA_SDK_DIR, 'arch', fuchsia_arch_name, 'sysroot')
+      # Build clang_rt runtime for Fuchsia in a separate build tree.
+      build_dir = os.path.join(LLVM_BUILD_DIR, 'fuchsia-' + target_arch)
+      if not os.path.exists(build_dir):
+        os.mkdir(os.path.join(build_dir))
+      os.chdir(build_dir)
+      target_spec = target_arch + '-fuchsia'
+      # TODO(thakis): Might have to pass -B here once sysroot contains
+      # binaries (e.g. gas for arm64?)
+      fuchsia_args = base_cmake_args + [
+        '-DLLVM_ENABLE_THREADS=OFF',
+        '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
+        '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
+        '-DCMAKE_LINKER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
+        '-DCMAKE_AR=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-ar'),
+        '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
+        '-DCMAKE_SYSTEM_NAME=Fuchsia',
+        '-DCMAKE_C_COMPILER_TARGET=%s-fuchsia' % target_arch,
+        '-DCMAKE_ASM_COMPILER_TARGET=%s-fuchsia' % target_arch,
+        '-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON',
+        '-DCMAKE_SYSROOT=%s' % toolchain_dir,
+        # TODO(thakis|scottmg): Use PER_TARGET_RUNTIME_DIR for all platforms.
+        # https://crbug.com/882485.
+        '-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON',
+
+        # These are necessary because otherwise CMake tries to build an
+        # executable to test to see if the compiler is working, but in doing so,
+        # it links against the builtins.a that we're about to build.
+        '-DCMAKE_C_COMPILER_WORKS=ON',
+        '-DCMAKE_ASM_COMPILER_WORKS=ON',
+        ]
+      RmCmakeCache('.')
+      RunCommand(['cmake'] +
+                 fuchsia_args +
+                 [os.path.join(COMPILER_RT_DIR, 'lib', 'builtins')])
+      builtins_a = 'libclang_rt.builtins.a'
+      RunCommand(['ninja', builtins_a])
+
+      # And copy it into the main build tree.
+      fuchsia_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
+                                         RELEASE_VERSION, target_spec, 'lib')
+      if not os.path.exists(fuchsia_lib_dst_dir):
+        os.makedirs(fuchsia_lib_dst_dir)
+      CopyFile(os.path.join(build_dir, target_spec, 'lib', builtins_a),
+               fuchsia_lib_dst_dir)
+
+  # Run tests.
+  if args.run_tests:
+    os.chdir(LLVM_BUILD_DIR)
+    RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64')
+  if args.run_tests:
+    if sys.platform == 'win32':
+      CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin'))
+    os.chdir(LLVM_BUILD_DIR)
+    RunCommand(['ninja', 'check-all'], msvc_arch='x64')
+
+  WriteStampFile(PACKAGE_VERSION, STAMP_FILE)
+  WriteStampFile(PACKAGE_VERSION, FORCE_HEAD_REVISION_FILE)
+
+  print('Clang build was successful.')
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py
index 8310d7c..4fcd017 100755
--- a/tools/clang/scripts/package.py
+++ b/tools/clang/scripts/package.py
@@ -216,8 +216,8 @@
     opt_flags = []
     if sys.platform.startswith('linux'):
       opt_flags += ['--lto-lld']
-    build_cmd = [sys.executable, os.path.join(THIS_DIR, 'update.py'),
-                 '--bootstrap', '--disable-asserts', '--force-local-build',
+    build_cmd = [sys.executable, os.path.join(THIS_DIR, 'build.py'),
+                 '--bootstrap', '--disable-asserts',
                  '--run-tests'] + opt_flags
     TeeCmd(build_cmd, log)
 
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index ab03116..2cf7df5c 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -3,20 +3,22 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-"""This script is used to download prebuilt clang binaries.
+"""This script is used to download prebuilt clang binaries. It runs as a
+"gclient hook" in Chromium checkouts.
 
-It is also used by package.py to build the prebuilt clang binaries."""
+It can also be run stand-alone as a convenient way of installing a well-tested
+near-tip-of-tree clang version:
+
+  $ curl -s https://raw.githubusercontent.com/chromium/chromium/master/tools/clang/scripts/update.py | python - --clang-dir=.
+"""
+
+# TODO: Running stand-alone won't work on Windows due to the dia dll copying.
 
 from __future__ import print_function
-
 import argparse
-import distutils.spawn
-import glob
 import os
-import pipes
 import re
 import shutil
-import subprocess
 import stat
 import sys
 import tarfile
@@ -36,57 +38,52 @@
 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
 CLANG_REVISION = '357692'
+CLANG_SUB_REVISION = 1
 
-# This is incremented when pushing a new build of Clang at the same revision.
-CLANG_SUB_REVISION=1
+PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
+RELEASE_VERSION = '9.0.0'
 
-PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
+CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE',
+    'https://commondatastorage.googleapis.com/chromium-browser-clang')
 
 # Path constants. (All of these should be absolute paths.)
 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
-GCLIENT_CONFIG = os.path.join(os.path.dirname(CHROMIUM_DIR), '.gclient')
-THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party')
-LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm')
-LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap')
-LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
-                                          'llvm-bootstrap-install')
-CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
                               'Release+Asserts')
-THREADS_ENABLED_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, 'threads_enabled')
-COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, 'compiler-rt')
-CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
-LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
-# compiler-rt is built as part of the regular LLVM build on Windows to get
-# the 64-bit runtime, and out-of-tree elsewhere.
-# TODO(thakis): Try to unify this.
-if sys.platform == 'win32':
-  COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
-else:
-  COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'compiler-rt')
-LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx')
-LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi')
-LLVM_BUILD_TOOLS_DIR = os.path.abspath(
-    os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
+
 STAMP_FILE = os.path.normpath(
-    os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision'))
-VERSION = '9.0.0'
-ANDROID_NDK_DIR = os.path.join(
-    CHROMIUM_DIR, 'third_party', 'android_ndk')
-FUCHSIA_SDK_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'fuchsia-sdk',
-                               'sdk')
+    os.path.join(LLVM_BUILD_DIR, '..', 'cr_build_revision'))
+FORCE_HEAD_REVISION_FILE = os.path.normpath(os.path.join(LLVM_BUILD_DIR, '..',
+                                                   'force_head_revision'))
 
-# URL for pre-built binaries.
-CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE',
-    'https://commondatastorage.googleapis.com/chromium-browser-clang')
 
-LLVM_REPO_URL='https://llvm.org/svn/llvm-project'
-if 'LLVM_REPO_URL' in os.environ:
-  LLVM_REPO_URL = os.environ['LLVM_REPO_URL']
+def RmTree(dir):
+  """Delete dir."""
+  def ChmodAndRetry(func, path, _):
+    # Subversion can leave read-only files around.
+    if not os.access(path, os.W_OK):
+      os.chmod(path, stat.S_IWUSR)
+      return func(path)
+    raise
+  shutil.rmtree(dir, onerror=ChmodAndRetry)
 
-BUG_REPORT_URL = ('https://crbug.com and run tools/clang/scripts/upload_crash.py'
-                  ' (only works inside Google) which will upload a report')
+
+def ReadStampFile(path):
+  """Return the contents of the stamp file, or '' if it doesn't exist."""
+  try:
+    with open(path, 'r') as f:
+      return f.read().rstrip()
+  except IOError:
+    return ''
+
+
+def WriteStampFile(s, path):
+  """Write s to the stamp file."""
+  EnsureDirExists(os.path.dirname(path))
+  with open(path, 'w') as f:
+    f.write(s)
+    f.write('\n')
 
 
 def DownloadUrl(url, output_file):
@@ -126,6 +123,7 @@
         raise e
       num_retries -= 1
       print('Retrying in %d s ...' % retry_wait_s)
+      sys.stdout.flush()
       time.sleep(retry_wait_s)
       retry_wait_s *= 2
 
@@ -154,235 +152,28 @@
       t.extractall(path=output_dir, members=members)
 
 
-def ReadStampFile(path=STAMP_FILE):
-  """Return the contents of the stamp file, or '' if it doesn't exist."""
+def GetPlatformUrlPrefix(platform):
+  if platform == 'win32' or platform == 'cygwin':
+    return CDS_URL + '/Win/'
+  if platform == 'darwin':
+    return CDS_URL + '/Mac/'
+  assert platform.startswith('linux')
+  return CDS_URL + '/Linux_x64/'
+
+
+def DownloadAndUnpackClangPackage(platform, output_dir, runtimes_only=False):
+  cds_file = "clang-%s.tgz" %  PACKAGE_VERSION
+  cds_full_url = GetPlatformUrlPrefix(platform) + cds_file
   try:
-    with open(path, 'r') as f:
-      return f.read().rstrip()
-  except IOError:
-    return ''
-
-
-def WriteStampFile(s, path=STAMP_FILE):
-  """Write s to the stamp file."""
-  EnsureDirExists(os.path.dirname(path))
-  with open(path, 'w') as f:
-    f.write(s)
-    f.write('\n')
-
-
-def GetSvnRevision(svn_repo):
-  """Returns current revision of the svn repo at svn_repo."""
-  svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True)
-  m = re.search(r'Revision: (\d+)', svn_info)
-  return m.group(1)
-
-
-def RmTree(dir):
-  """Delete dir."""
-  def ChmodAndRetry(func, path, _):
-    # Subversion can leave read-only files around.
-    if not os.access(path, os.W_OK):
-      os.chmod(path, stat.S_IWUSR)
-      return func(path)
-    raise
-
-  shutil.rmtree(dir, onerror=ChmodAndRetry)
-
-
-def RmCmakeCache(dir):
-  """Delete CMake cache related files from dir."""
-  for dirpath, dirs, files in os.walk(dir):
-    if 'CMakeCache.txt' in files:
-      os.remove(os.path.join(dirpath, 'CMakeCache.txt'))
-    if 'CMakeFiles' in dirs:
-      RmTree(os.path.join(dirpath, 'CMakeFiles'))
-
-
-def RunCommand(command, msvc_arch=None, env=None, fail_hard=True):
-  """Run command and return success (True) or failure; or if fail_hard is
-     True, exit on failure.  If msvc_arch is set, runs the command in a
-     shell with the msvc tools for that architecture."""
-
-  if msvc_arch and sys.platform == 'win32':
-    command = [os.path.join(GetWinSDKDir(), 'bin', 'SetEnv.cmd'),
-               "/" + msvc_arch, '&&'] + command
-
-  # https://docs.python.org/2/library/subprocess.html:
-  # "On Unix with shell=True [...] if args is a sequence, the first item
-  # specifies the command string, and any additional items will be treated as
-  # additional arguments to the shell itself.  That is to say, Popen does the
-  # equivalent of:
-  #   Popen(['/bin/sh', '-c', args[0], args[1], ...])"
-  #
-  # We want to pass additional arguments to command[0], not to the shell,
-  # so manually join everything into a single string.
-  # Annoyingly, for "svn co url c:\path", pipes.quote() thinks that it should
-  # quote c:\path but svn can't handle quoted paths on Windows.  Since on
-  # Windows follow-on args are passed to args[0] instead of the shell, don't
-  # do the single-string transformation there.
-  if sys.platform != 'win32':
-    command = ' '.join([pipes.quote(c) for c in command])
-  print('Running', command)
-  if subprocess.call(command, env=env, shell=True) == 0:
-    return True
-  print('Failed.')
-  if fail_hard:
+    path_prefix = None
+    if runtimes_only:
+      path_prefix = 'lib/clang/' + RELEASE_VERSION + '/lib/'
+    DownloadAndUnpack(cds_full_url, output_dir, path_prefix)
+  except urllib.URLError:
+    print('Failed to download prebuilt clang %s' % cds_file)
+    print('Use --force-local-build if you want to build locally.')
+    print('Exiting.')
     sys.exit(1)
-  return False
-
-
-def CopyFile(src, dst):
-  """Copy a file from src to dst."""
-  print("Copying %s to %s" % (src, dst))
-  shutil.copy(src, dst)
-
-
-def CopyDirectoryContents(src, dst):
-  """Copy the files from directory src to dst."""
-  dst = os.path.realpath(dst)  # realpath() in case dst ends in /..
-  EnsureDirExists(dst)
-  for f in os.listdir(src):
-    CopyFile(os.path.join(src, f), dst)
-
-
-def Checkout(name, url, dir):
-  """Checkout the SVN module at url into dir. Use name for the log message."""
-  print("Checking out %s r%s into '%s'" % (name, CLANG_REVISION, dir))
-
-  command = ['svn', 'checkout', '--force', url + '@' + CLANG_REVISION, dir]
-  if RunCommand(command, fail_hard=False):
-    return
-
-  if os.path.isdir(dir):
-    print("Removing %s." % dir)
-    RmTree(dir)
-
-  print("Retrying.")
-  RunCommand(command)
-
-
-def CheckoutRepos(args):
-  if args.skip_checkout:
-    return
-
-  Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
-  Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
-  if True:
-    Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
-  elif os.path.exists(LLD_DIR):
-    # In case someone sends a tryjob that temporary adds lld to the checkout,
-    # make sure it's not around on future builds.
-    RmTree(LLD_DIR)
-  Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
-  if sys.platform == 'darwin':
-    # clang needs a libc++ checkout, else -stdlib=libc++ won't find includes
-    # (i.e. this is needed for bootstrap builds).
-    Checkout('libcxx', LLVM_REPO_URL + '/libcxx/trunk', LIBCXX_DIR)
-    # We used to check out libcxxabi on OS X; we no longer need that.
-    if os.path.exists(LIBCXXABI_DIR):
-      RmTree(LIBCXXABI_DIR)
-
-
-def DeleteChromeToolsShim():
-  OLD_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'zzz-chrometools')
-  shutil.rmtree(OLD_SHIM_DIR, ignore_errors=True)
-  shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True)
-
-
-def CreateChromeToolsShim():
-  """Hooks the Chrome tools into the LLVM build.
-
-  Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build
-  detects implicit tools in the tools subdirectory, so this helper install a
-  shim CMakeLists.txt that forwards to the real directory for the Chrome tools.
-
-  Note that the shim directory name intentionally has no - or _. The implicit
-  tool detection logic munges them in a weird way."""
-  assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_')
-  os.mkdir(CHROME_TOOLS_SHIM_DIR)
-  with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f:
-    f.write('# Automatically generated by tools/clang/scripts/update.py. ' +
-            'Do not edit.\n')
-    f.write('# Since tools/clang is located in another directory, use the \n')
-    f.write('# two arg version to specify where build artifacts go. CMake\n')
-    f.write('# disallows reuse of the same binary dir for multiple source\n')
-    f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
-    f.write('if (CHROMIUM_TOOLS_SRC)\n')
-    f.write('  add_subdirectory(${CHROMIUM_TOOLS_SRC} ' +
-              '${CMAKE_CURRENT_BINARY_DIR}/a)\n')
-    f.write('endif (CHROMIUM_TOOLS_SRC)\n')
-
-
-def AddSvnToPathOnWin():
-  """Download svn.exe and add it to PATH."""
-  if sys.platform != 'win32':
-    return
-  svn_ver = 'svn-1.6.6-win'
-  svn_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, svn_ver)
-  if not os.path.exists(svn_dir):
-    DownloadAndUnpack(CDS_URL + '/tools/%s.zip' % svn_ver, LLVM_BUILD_TOOLS_DIR)
-  os.environ['PATH'] = svn_dir + os.pathsep + os.environ.get('PATH', '')
-
-
-def AddCMakeToPath(args):
-  """Download CMake and add it to PATH."""
-  if args.use_system_cmake:
-    return
-
-  if sys.platform == 'win32':
-    zip_name = 'cmake-3.12.1-win32-x86.zip'
-    dir_name = ['cmake-3.12.1-win32-x86', 'bin']
-  elif sys.platform == 'darwin':
-    zip_name = 'cmake-3.12.1-Darwin-x86_64.tar.gz'
-    dir_name = ['cmake-3.12.1-Darwin-x86_64', 'CMake.app', 'Contents', 'bin']
-  else:
-    zip_name = 'cmake-3.12.1-Linux-x86_64.tar.gz'
-    dir_name = ['cmake-3.12.1-Linux-x86_64', 'bin']
-
-  cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, *dir_name)
-  if not os.path.exists(cmake_dir):
-    DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
-  os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
-
-
-def AddGnuWinToPath():
-  """Download some GNU win tools and add them to PATH."""
-  if sys.platform != 'win32':
-    return
-
-  gnuwin_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gnuwin')
-  GNUWIN_VERSION = '9'
-  GNUWIN_STAMP = os.path.join(gnuwin_dir, 'stamp')
-  if ReadStampFile(GNUWIN_STAMP) == GNUWIN_VERSION:
-    print('GNU Win tools already up to date.')
-  else:
-    zip_name = 'gnuwin-%s.zip' % GNUWIN_VERSION
-    DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
-    WriteStampFile(GNUWIN_VERSION, GNUWIN_STAMP)
-
-  os.environ['PATH'] = gnuwin_dir + os.pathsep + os.environ.get('PATH', '')
-
-  # find.exe, mv.exe and rm.exe are from MSYS (see crrev.com/389632). MSYS uses
-  # Cygwin under the hood, and initializing Cygwin has a race-condition when
-  # getting group and user data from the Active Directory is slow. To work
-  # around this, use a horrible hack telling it not to do that.
-  # See https://crbug.com/905289
-  etc = os.path.join(gnuwin_dir, '..', '..', 'etc')
-  EnsureDirExists(etc)
-  with open(os.path.join(etc, 'nsswitch.conf'), 'w') as f:
-    f.write('passwd: files\n')
-    f.write('group: files\n')
-
-
-def SetMacXcodePath():
-  """Set DEVELOPER_DIR to the path to hermetic Xcode.app on Mac OS X."""
-  if sys.platform != 'darwin':
-    return
-
-  xcode_path = os.path.join(CHROMIUM_DIR, 'build', 'mac_files', 'Xcode.app')
-  if os.path.exists(xcode_path):
-    os.environ['DEVELOPER_DIR'] = xcode_path
 
 
 win_sdk_dir = None
@@ -425,55 +216,21 @@
   return win_sdk_dir
 
 
+def CopyFile(src, dst):
+  """Copy a file from src to dst."""
+  print("Copying %s to %s" % (src, dst))
+  shutil.copy(src, dst)
+
+
 def CopyDiaDllTo(target_dir):
   # This script always wants to use the 64-bit msdia*.dll.
   GetWinSDKDir()
   CopyFile(dia_dll, target_dir)
 
 
-def VeryifyVersionOfBuiltClangMatchesVERSION():
-  """Checks that `clang --version` outputs VERSION.  If this fails, VERSION
-  in this file is out-of-date and needs to be updated (possibly in an
-  `if args.llvm_force_head_revision:` block in main() first)."""
-  clang = os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')
-  if sys.platform == 'win32':
-    # TODO: Parse `clang-cl /?` output for built clang's version and check that
-    # to check the binary we're actually shipping? But clang-cl.exe is just
-    # a copy of clang.exe, so this does check the same thing.
-    clang += '.exe'
-  version_out = subprocess.check_output([clang, '--version'])
-  version_out = re.match(r'clang version ([0-9.]+)', version_out).group(1)
-  if version_out != VERSION:
-    print('unexpected clang version %s (not %s), update VERSION in update.py'
-          % (version_out, VERSION))
-    sys.exit(1)
+def UpdateClang():
+  GCLIENT_CONFIG = os.path.join(os.path.dirname(CHROMIUM_DIR), '.gclient')
 
-
-def GetPlatformUrlPrefix(platform):
-  if platform == 'win32' or platform == 'cygwin':
-    return CDS_URL + '/Win/'
-  if platform == 'darwin':
-    return CDS_URL + '/Mac/'
-  assert platform.startswith('linux')
-  return CDS_URL + '/Linux_x64/'
-
-
-def DownloadAndUnpackClangPackage(platform, runtimes_only=False):
-  cds_file = "clang-%s.tgz" %  PACKAGE_VERSION
-  cds_full_url = GetPlatformUrlPrefix(platform) + cds_file
-  try:
-    path_prefix = None
-    if runtimes_only:
-      path_prefix = 'lib/clang/' + VERSION + '/lib/'
-    DownloadAndUnpack(cds_full_url, LLVM_BUILD_DIR, path_prefix)
-  except urllib.URLError:
-    print('Failed to download prebuilt clang %s' % cds_file)
-    print('Use --force-local-build if you want to build locally.')
-    print('Exiting.')
-    sys.exit(1)
-
-
-def UpdateClang(args):
   # Read target_os from .gclient so we know which non-native runtimes we need.
   # TODO(pcc): See if we can download just the runtimes instead of the entire
   # clang package, and do that from DEPS instead of here.
@@ -486,565 +243,79 @@
     pass
 
   expected_stamp = ','.join([PACKAGE_VERSION] + target_os)
-  if ReadStampFile() == expected_stamp and not args.force_local_build:
+  if ReadStampFile(STAMP_FILE) == expected_stamp:
     return 0
 
-  # Reset the stamp file in case the build is unsuccessful.
-  WriteStampFile('')
+  if os.path.exists(LLVM_BUILD_DIR):
+    RmTree(LLVM_BUILD_DIR)
 
-  if not args.force_local_build:
-    if os.path.exists(LLVM_BUILD_DIR):
-      RmTree(LLVM_BUILD_DIR)
-
-    DownloadAndUnpackClangPackage(sys.platform)
-    if 'win' in target_os:
-      DownloadAndUnpackClangPackage('win32', runtimes_only=True)
-    if sys.platform == 'win32':
-      CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin'))
-    WriteStampFile(expected_stamp)
-    return 0
-
-  if args.with_android and not os.path.exists(ANDROID_NDK_DIR):
-    print('Android NDK not found at ' + ANDROID_NDK_DIR)
-    print('The Android NDK is needed to build a Clang whose -fsanitize=address')
-    print('works on Android. See ')
-    print('https://www.chromium.org/developers/how-tos/android-build-instructions')
-    print('for how to install the NDK, or pass --without-android.')
-    return 1
-
-  if args.with_fuchsia and not os.path.exists(FUCHSIA_SDK_DIR):
-    print('Fuchsia SDK not found at ' + FUCHSIA_SDK_DIR)
-    print('The Fuchsia SDK is needed to build libclang_rt for Fuchsia.')
-    print('Install the Fuchsia SDK by adding fuchsia to the ')
-    print('target_os section in your .gclient and running hooks, ')
-    print('or pass --without-fuchsia.')
-    print('https://chromium.googlesource.com/chromium/src/+/master/docs/fuchsia_build_instructions.md')
-    print('for general Fuchsia build instructions.')
-    return 1
-
-  print('Locally building Clang %s...' % PACKAGE_VERSION)
-
-  AddCMakeToPath(args)
-  AddGnuWinToPath()
-
-  DeleteChromeToolsShim()
-
-  CheckoutRepos(args)
-
-  if args.skip_build:
-    return
-
-  cc, cxx = None, None
-  libstdcpp = None
-
-  cflags = []
-  cxxflags = []
-  ldflags = []
-
-  targets = 'AArch64;ARM;Mips;PowerPC;SystemZ;WebAssembly;X86'
-  base_cmake_args = ['-GNinja',
-                     '-DCMAKE_BUILD_TYPE=Release',
-                     '-DLLVM_ENABLE_ASSERTIONS=%s' %
-                         ('OFF' if args.disable_asserts else 'ON'),
-                     '-DLLVM_ENABLE_PIC=OFF',
-                     '-DLLVM_ENABLE_TERMINFO=OFF',
-                     '-DLLVM_TARGETS_TO_BUILD=' + targets,
-                     # Statically link MSVCRT to avoid DLL dependencies.
-                     '-DLLVM_USE_CRT_RELEASE=MT',
-                     '-DCLANG_PLUGIN_SUPPORT=OFF',
-                     '-DCLANG_ENABLE_STATIC_ANALYZER=OFF',
-                     '-DCLANG_ENABLE_ARCMT=OFF',
-                     # TODO(crbug.com/929645): Use newer toolchain to host.
-                     '-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON',
-                     '-DBUG_REPORT_URL=' + BUG_REPORT_URL,
-                     ]
-
-  if sys.platform != 'win32':
-    # libxml2 is required by the Win manifest merging tool used in cross-builds.
-    base_cmake_args.append('-DLLVM_ENABLE_LIBXML2=FORCE_ON')
-
-  if args.bootstrap:
-    print('Building bootstrap compiler')
-    EnsureDirExists(LLVM_BOOTSTRAP_DIR)
-    os.chdir(LLVM_BOOTSTRAP_DIR)
-    bootstrap_args = base_cmake_args + [
-        '-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64',
-        '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR,
-        '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
-        '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
-        # Ignore args.disable_asserts for the bootstrap compiler.
-        '-DLLVM_ENABLE_ASSERTIONS=ON',
-        ]
-    if cc is not None:  bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc)
-    if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
-    RmCmakeCache('.')
-    RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64')
-    RunCommand(['ninja'], msvc_arch='x64')
-    if args.run_tests:
-      if sys.platform == 'win32':
-        CopyDiaDllTo(os.path.join(LLVM_BOOTSTRAP_DIR, 'bin'))
-      RunCommand(['ninja', 'check-all'], msvc_arch='x64')
-    RunCommand(['ninja', 'install'], msvc_arch='x64')
-
-    if sys.platform == 'win32':
-      cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
-      cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
-      # CMake has a hard time with backslashes in compiler paths:
-      # https://stackoverflow.com/questions/13050827
-      cc = cc.replace('\\', '/')
-      cxx = cxx.replace('\\', '/')
-    else:
-      cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang')
-      cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang++')
-
-    print('Building final compiler')
-
-  # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is
-  # needed, on OS X it requires libc++. clang only automatically links to libc++
-  # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run
-  # on OS X versions as old as 10.7.
-  deployment_target = ''
-
-  if sys.platform == 'darwin' and args.bootstrap:
-    # When building on 10.9, /usr/include usually doesn't exist, and while
-    # Xcode's clang automatically sets a sysroot, self-built clangs don't.
-    cflags = ['-isysroot', subprocess.check_output(
-        ['xcrun', '--show-sdk-path']).rstrip()]
-    cxxflags = ['-stdlib=libc++'] + cflags
-    ldflags += ['-stdlib=libc++']
-    deployment_target = '10.7'
-    # Running libc++ tests takes a long time. Since it was only needed for
-    # the install step above, don't build it as part of the main build.
-    # This makes running package.py over 10% faster (30 min instead of 34 min)
-    RmTree(LIBCXX_DIR)
-
-
-  # If building at head, define a macro that plugins can use for #ifdefing
-  # out code that builds at head, but not at CLANG_REVISION or vice versa.
-  if args.llvm_force_head_revision:
-    cflags += ['-DLLVM_FORCE_HEAD_REVISION']
-    cxxflags += ['-DLLVM_FORCE_HEAD_REVISION']
-
-  # Build PDBs for archival on Windows.  Don't use RelWithDebInfo since it
-  # has different optimization defaults than Release.
-  # Also disable stack cookies (/GS-) for performance.
+  DownloadAndUnpackClangPackage(sys.platform, LLVM_BUILD_DIR)
+  if 'win' in target_os:
+    DownloadAndUnpackClangPackage('win32', LLVM_BUILD_DIR, runtimes_only=True)
   if sys.platform == 'win32':
-    cflags += ['/Zi', '/GS-']
-    cxxflags += ['/Zi', '/GS-']
-    ldflags += ['/DEBUG', '/OPT:REF', '/OPT:ICF']
+    CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin'))
+  WriteStampFile(expected_stamp, STAMP_FILE)
 
-  deployment_env = None
-  if deployment_target:
-    deployment_env = os.environ.copy()
-    deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
-
-  # Build lld and code coverage tools. This is done separately from the rest of
-  # the build because these tools require threading support.
-  tools_with_threading = [ 'dsymutil', 'lld', 'llvm-cov', 'llvm-profdata' ]
-  print('Building the following tools with threading support: %s' %
-        str(tools_with_threading))
-
-  if os.path.exists(THREADS_ENABLED_BUILD_DIR):
-    RmTree(THREADS_ENABLED_BUILD_DIR)
-  EnsureDirExists(THREADS_ENABLED_BUILD_DIR)
-  os.chdir(THREADS_ENABLED_BUILD_DIR)
-
-  threads_enabled_cmake_args = base_cmake_args + [
-      '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
-      '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
-      '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
-      '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
-      '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags)]
-  if cc is not None:
-    threads_enabled_cmake_args.append('-DCMAKE_C_COMPILER=' + cc)
-  if cxx is not None:
-    threads_enabled_cmake_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
-
-  if args.lto_lld:
-    # Build lld with LTO. That speeds up the linker by ~10%.
-    # We only use LTO for Linux now.
-    #
-    # The linker expects all archive members to have symbol tables, so the
-    # archiver needs to be able to create symbol tables for bitcode files.
-    # GNU ar and ranlib don't understand bitcode files, but llvm-ar and
-    # llvm-ranlib do, so use them.
-    ar = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'llvm-ar')
-    ranlib = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'llvm-ranlib')
-    threads_enabled_cmake_args += [
-        '-DCMAKE_AR=' + ar,
-        '-DCMAKE_RANLIB=' + ranlib,
-        '-DLLVM_ENABLE_LTO=thin',
-        '-DLLVM_USE_LINKER=lld']
-
-  RmCmakeCache('.')
-  RunCommand(['cmake'] + threads_enabled_cmake_args + [LLVM_DIR],
-             msvc_arch='x64', env=deployment_env)
-  RunCommand(['ninja'] + tools_with_threading, msvc_arch='x64')
-
-  # Build clang and other tools.
-  CreateChromeToolsShim()
-
-  cmake_args = []
-  # TODO(thakis): Unconditionally append this to base_cmake_args instead once
-  # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
-  cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
-  if cc is not None:  cc_args.append('-DCMAKE_C_COMPILER=' + cc)
-  if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
-  default_tools = ['plugins', 'blink_gc_plugin', 'translation_unit']
-  chrome_tools = list(set(default_tools + args.extra_tools))
-  cmake_args += base_cmake_args + [
-      '-DLLVM_ENABLE_THREADS=OFF',
-      '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
-      '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
-      '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
-      '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
-      '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags),
-      '-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR,
-      '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
-      '-DCHROMIUM_TOOLS=%s' % ';'.join(chrome_tools)]
-
-  EnsureDirExists(LLVM_BUILD_DIR)
-  os.chdir(LLVM_BUILD_DIR)
-  RmCmakeCache('.')
-  RunCommand(['cmake'] + cmake_args + [LLVM_DIR],
-             msvc_arch='x64', env=deployment_env)
-  RunCommand(['ninja'], msvc_arch='x64')
-
-  # Copy in the threaded versions of lld and other tools.
-  if sys.platform == 'win32':
-    CopyFile(os.path.join(THREADS_ENABLED_BUILD_DIR, 'bin', 'lld-link.exe'),
-             os.path.join(LLVM_BUILD_DIR, 'bin'))
-    CopyFile(os.path.join(THREADS_ENABLED_BUILD_DIR, 'bin', 'lld.pdb'),
-             os.path.join(LLVM_BUILD_DIR, 'bin'))
-  else:
-    for tool in tools_with_threading:
-      CopyFile(os.path.join(THREADS_ENABLED_BUILD_DIR, 'bin', tool),
-               os.path.join(LLVM_BUILD_DIR, 'bin'))
-
-  if chrome_tools:
-    # If any Chromium tools were built, install those now.
-    RunCommand(['ninja', 'cr-install'], msvc_arch='x64')
-
-  VeryifyVersionOfBuiltClangMatchesVERSION()
-
-  # Do an out-of-tree build of compiler-rt.
-  # On Windows, this is used to get the 32-bit ASan run-time.
-  # TODO(hans): Remove once the regular build above produces this.
-  # On Mac and Linux, this is used to get the regular 64-bit run-time.
-  # Do a clobbered build due to cmake changes.
-  if os.path.isdir(COMPILER_RT_BUILD_DIR):
-    RmTree(COMPILER_RT_BUILD_DIR)
-  os.makedirs(COMPILER_RT_BUILD_DIR)
-  os.chdir(COMPILER_RT_BUILD_DIR)
-  # TODO(thakis): Add this once compiler-rt can build with clang-cl (see
-  # above).
-  #if args.bootstrap and sys.platform == 'win32':
-    # The bootstrap compiler produces 64-bit binaries by default.
-    #cflags += ['-m32']
-    #cxxflags += ['-m32']
-  compiler_rt_args = base_cmake_args + [
-      '-DLLVM_ENABLE_THREADS=OFF',
-      '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
-      '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)]
-  if sys.platform == 'darwin':
-    compiler_rt_args += ['-DCOMPILER_RT_ENABLE_IOS=ON']
-  if sys.platform != 'win32':
-    compiler_rt_args += ['-DLLVM_CONFIG_PATH=' +
-                         os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config'),
-                        '-DSANITIZER_MIN_OSX_VERSION="10.7"']
-  # compiler-rt is part of the llvm checkout on Windows but a stand-alone
-  # directory elsewhere, see the TODO above COMPILER_RT_DIR.
-  RmCmakeCache('.')
-  RunCommand(['cmake'] + compiler_rt_args +
-             [LLVM_DIR if sys.platform == 'win32' else COMPILER_RT_DIR],
-             msvc_arch='x86', env=deployment_env)
-  RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86')
-  if sys.platform != 'win32':
-    RunCommand(['ninja', 'fuzzer'])
-
-  # Copy select output to the main tree.
-  # TODO(hans): Make this (and the .gypi and .isolate files) version number
-  # independent.
-  if sys.platform == 'win32':
-    platform = 'windows'
-  elif sys.platform == 'darwin':
-    platform = 'darwin'
-  else:
-    assert sys.platform.startswith('linux')
-    platform = 'linux'
-  rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', platform)
-  if sys.platform == 'win32':
-    # TODO(thakis): This too is due to compiler-rt being part of the checkout
-    # on Windows, see TODO above COMPILER_RT_DIR.
-    rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
-                                  VERSION, 'lib', platform)
-  rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', VERSION, 'lib',
-                                platform)
-  # Blacklists:
-  CopyDirectoryContents(os.path.join(rt_lib_src_dir, '..', '..', 'share'),
-                        os.path.join(rt_lib_dst_dir, '..', '..', 'share'))
-  # Headers:
-  if sys.platform != 'win32':
-    CopyDirectoryContents(
-        os.path.join(COMPILER_RT_BUILD_DIR, 'include/sanitizer'),
-        os.path.join(LLVM_BUILD_DIR, 'lib/clang', VERSION, 'include/sanitizer'))
-  # Static and dynamic libraries:
-  CopyDirectoryContents(rt_lib_src_dir, rt_lib_dst_dir)
-  if sys.platform == 'darwin':
-    for dylib in glob.glob(os.path.join(rt_lib_dst_dir, '*.dylib')):
-      # Fix LC_ID_DYLIB for the ASan dynamic libraries to be relative to
-      # @executable_path.
-      # TODO(glider): this is transitional. We'll need to fix the dylib
-      # name either in our build system, or in Clang. See also
-      # http://crbug.com/344836.
-      subprocess.call(['install_name_tool', '-id',
-                       '@executable_path/' + os.path.basename(dylib), dylib])
-
-  if args.with_android:
-    make_toolchain = os.path.join(
-        ANDROID_NDK_DIR, 'build', 'tools', 'make_standalone_toolchain.py')
-    for target_arch in ['aarch64', 'arm', 'i686']:
-      # Make standalone Android toolchain for target_arch.
-      toolchain_dir = os.path.join(
-          LLVM_BUILD_DIR, 'android-toolchain-' + target_arch)
-      api_level = '21' if target_arch == 'aarch64' else '19'
-      RunCommand([
-          make_toolchain,
-          '--api=' + api_level,
-          '--force',
-          '--install-dir=%s' % toolchain_dir,
-          '--stl=libc++',
-          '--arch=' + {
-              'aarch64': 'arm64',
-              'arm': 'arm',
-              'i686': 'x86',
-          }[target_arch]])
-
-      # NDK r16 "helpfully" installs libc++ as libstdc++ "so the compiler will
-      # pick it up by default". Only these days, the compiler tries to find
-      # libc++ instead. See https://crbug.com/902270.
-      shutil.copy(os.path.join(toolchain_dir, 'sysroot/usr/lib/libstdc++.a'),
-                  os.path.join(toolchain_dir, 'sysroot/usr/lib/libc++.a'))
-      shutil.copy(os.path.join(toolchain_dir, 'sysroot/usr/lib/libstdc++.so'),
-                  os.path.join(toolchain_dir, 'sysroot/usr/lib/libc++.so'))
-
-      # Build compiler-rt runtimes needed for Android in a separate build tree.
-      build_dir = os.path.join(LLVM_BUILD_DIR, 'android-' + target_arch)
-      if not os.path.exists(build_dir):
-        os.mkdir(os.path.join(build_dir))
-      os.chdir(build_dir)
-      target_triple = target_arch
-      if target_arch == 'arm':
-        target_triple = 'armv7'
-      target_triple += '-linux-android' + api_level
-      cflags = ['--target=%s' % target_triple,
-                '--sysroot=%s/sysroot' % toolchain_dir,
-                '-B%s' % toolchain_dir]
-      android_args = base_cmake_args + [
-        '-DLLVM_ENABLE_THREADS=OFF',
-        '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
-        '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
-        '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
-        '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
-        '-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
-        '-DCMAKE_ASM_FLAGS=' + ' '.join(cflags),
-        '-DSANITIZER_CXX_ABI=libcxxabi',
-        '-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-u__cxa_demangle',
-        '-DANDROID=1']
-      RmCmakeCache('.')
-      RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR])
-
-      # We use ASan i686 build for fuzzing.
-      libs_want = ['lib/linux/libclang_rt.asan-{0}-android.so']
-      if target_arch in ['aarch64', 'arm']:
-        libs_want += [
-            'lib/linux/libclang_rt.ubsan_standalone-{0}-android.so',
-            'lib/linux/libclang_rt.profile-{0}-android.a',
-        ]
-      if target_arch == 'aarch64':
-        libs_want += ['lib/linux/libclang_rt.hwasan-{0}-android.so']
-      libs_want = [lib.format(target_arch) for lib in libs_want]
-      RunCommand(['ninja'] + libs_want)
-
-      # And copy them into the main build tree.
-      for p in libs_want:
-        shutil.copy(p, rt_lib_dst_dir)
-
-  if args.with_fuchsia:
-    # Fuchsia links against libclang_rt.builtins-<arch>.a instead of libgcc.a.
-    for target_arch in ['aarch64', 'x86_64']:
-      fuchsia_arch_name = {'aarch64': 'arm64', 'x86_64': 'x64'}[target_arch]
-      toolchain_dir = os.path.join(
-          FUCHSIA_SDK_DIR, 'arch', fuchsia_arch_name, 'sysroot')
-      # Build clang_rt runtime for Fuchsia in a separate build tree.
-      build_dir = os.path.join(LLVM_BUILD_DIR, 'fuchsia-' + target_arch)
-      if not os.path.exists(build_dir):
-        os.mkdir(os.path.join(build_dir))
-      os.chdir(build_dir)
-      target_spec = target_arch + '-fuchsia'
-      # TODO(thakis): Might have to pass -B here once sysroot contains
-      # binaries (e.g. gas for arm64?)
-      fuchsia_args = base_cmake_args + [
-        '-DLLVM_ENABLE_THREADS=OFF',
-        '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
-        '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
-        '-DCMAKE_LINKER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
-        '-DCMAKE_AR=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-ar'),
-        '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
-        '-DCMAKE_SYSTEM_NAME=Fuchsia',
-        '-DCMAKE_C_COMPILER_TARGET=%s-fuchsia' % target_arch,
-        '-DCMAKE_ASM_COMPILER_TARGET=%s-fuchsia' % target_arch,
-        '-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON',
-        '-DCMAKE_SYSROOT=%s' % toolchain_dir,
-        # TODO(thakis|scottmg): Use PER_TARGET_RUNTIME_DIR for all platforms.
-        # https://crbug.com/882485.
-        '-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON',
-
-        # These are necessary because otherwise CMake tries to build an
-        # executable to test to see if the compiler is working, but in doing so,
-        # it links against the builtins.a that we're about to build.
-        '-DCMAKE_C_COMPILER_WORKS=ON',
-        '-DCMAKE_ASM_COMPILER_WORKS=ON',
-        ]
-      RmCmakeCache('.')
-      RunCommand(['cmake'] +
-                 fuchsia_args +
-                 [os.path.join(COMPILER_RT_DIR, 'lib', 'builtins')])
-      builtins_a = 'libclang_rt.builtins.a'
-      RunCommand(['ninja', builtins_a])
-
-      # And copy it into the main build tree.
-      fuchsia_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
-                                         VERSION, target_spec, 'lib')
-      if not os.path.exists(fuchsia_lib_dst_dir):
-        os.makedirs(fuchsia_lib_dst_dir)
-      CopyFile(os.path.join(build_dir, target_spec, 'lib', builtins_a),
-               fuchsia_lib_dst_dir)
-
-  # Run tests.
-  if args.run_tests or args.llvm_force_head_revision:
-    os.chdir(LLVM_BUILD_DIR)
-    RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64')
-  if args.run_tests:
-    if sys.platform == 'win32':
-      CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin'))
-    os.chdir(LLVM_BUILD_DIR)
-    RunCommand(['ninja', 'check-all'], msvc_arch='x64')
-
-  WriteStampFile(PACKAGE_VERSION)
-  print('Clang update was successful.')
   return 0
 
 
-def gn_arg(v):
-  if v == 'True':
-    return True
-  if v == 'False':
-    return False
-  raise argparse.ArgumentTypeError('Expected one of %r or %r' % (
-      'True', 'False'))
-
-
 def main():
-  parser = argparse.ArgumentParser(description='Build Clang.')
-  parser.add_argument('--bootstrap', action='store_true',
-                      help='first build clang with CC, then with itself.')
-  parser.add_argument('--disable-asserts', action='store_true',
-                      help='build with asserts disabled')
+  # TODO: Add an argument to download optional packages and remove the various
+  # download_ scripts we currently have for that.
+
+  parser = argparse.ArgumentParser(description='Update clang.')
+  parser.add_argument('--clang-dir',
+                      help='Where to extract the clang package.')
   parser.add_argument('--force-local-build', action='store_true',
-                      help="don't try to download prebuild binaries")
-  parser.add_argument('--gcc-toolchain', help='set the version for which gcc '
-                      'version be used for building; --gcc-toolchain=/opt/foo '
-                      'picks /opt/foo/bin/gcc')
-  parser.add_argument('--lto-lld', action='store_true',
-                      help='build lld with LTO')
-  parser.add_argument('--llvm-force-head-revision', action='store_true',
-                      help=('use the revision in the repo when printing '
-                            'the revision'))
+                      help='(no longer used)')
   parser.add_argument('--print-revision', action='store_true',
-                      help='print current clang revision and exit.')
+                      help='Print current clang revision and exit.')
+  parser.add_argument('--llvm-force-head-revision', action='store_true',
+                      help='Print locally built revision with --print-revision')
   parser.add_argument('--print-clang-version', action='store_true',
-                      help='print current clang version (e.g. x.y.z) and exit.')
-  parser.add_argument('--run-tests', action='store_true',
-                      help='run tests after building; only for local builds')
-  parser.add_argument('--skip-build', action='store_true',
-                      help='do not build anything')
-  parser.add_argument('--skip-checkout', action='store_true',
-                      help='do not create or update any checkouts')
-  parser.add_argument('--extra-tools', nargs='*', default=[],
-                      help='select additional chrome tools to build')
-  parser.add_argument('--use-system-cmake', action='store_true',
-                      help='use the cmake from PATH instead of downloading '
-                      'and using prebuilt cmake binaries')
+                      help=('Print current clang release version (e.g. 9.0.0) '
+                            'and exit.'))
   parser.add_argument('--verify-version',
-                      help='verify that clang has the passed-in version')
-  parser.add_argument('--with-android', type=gn_arg, nargs='?', const=True,
-                      help='build the Android ASan runtime (linux only)',
-                      default=sys.platform.startswith('linux'))
-  parser.add_argument('--without-android', action='store_false',
-                      help='don\'t build Android ASan runtime (linux only)',
-                      dest='with_android')
-  parser.add_argument('--without-fuchsia', action='store_false',
-                      help='don\'t build Fuchsia clang_rt runtime (linux/mac)',
-                      dest='with_fuchsia',
-                      default=sys.platform in ('linux2', 'darwin'))
+                      help='Verify that clang has the passed-in version.')
   args = parser.parse_args()
 
-  if (os.environ.get('LLVM_FORCE_HEAD_REVISION', '0') in ('1', 'YES')):
-    args.llvm_force_head_revision = True
-
-  if args.lto_lld and not args.bootstrap:
-    print('--lto-lld requires --bootstrap')
+  if args.force_local_build:
+    print(('update.py --force-local-build is no longer used to build clang; '
+           'use build.py instead.'))
     return 1
-  if args.lto_lld and not sys.platform.startswith('linux'):
-    print('--lto-lld is only effective on Linux. Ignoring the option.')
-    args.lto_lld = False
 
-  # Get svn if we're going to use it to check the revision or do a local build.
-  if args.llvm_force_head_revision or args.force_local_build:
-    AddSvnToPathOnWin()
-
-  if args.verify_version and args.verify_version != VERSION:
-    print('VERSION is %s but --verify-version argument was %s, exiting.' % (
-        VERSION, args.verify_version))
+  if args.verify_version and args.verify_version != RELEASE_VERSION:
+    print('RELEASE_VERSION is %s but --verify-version argument was %s.' % (
+        RELEASE_VERSION, args.verify_version))
     print('clang_version in build/toolchain/toolchain.gni is likely outdated.')
     return 1
 
-  # DEVELOPER_DIR needs to be set when Xcode isn't in a standard location
-  # and xcode-select wasn't run.  This is needed for running clang and ld
-  # for the build done by this script, but it's also needed for running
-  # macOS system svn, so this needs to happen before calling functions using
-  # svn.
-  SetMacXcodePath()
+  if args.print_clang_version:
+    print(RELEASE_VERSION)
+    return 0
 
-  global CLANG_REVISION, PACKAGE_VERSION
   if args.print_revision:
     if args.llvm_force_head_revision:
-      print(GetSvnRevision(LLVM_DIR))
-    else:
-      print(PACKAGE_VERSION)
-    return 0
+      force_head_revision = ReadStampFile(FORCE_HEAD_REVISION_FILE)
+      if force_head_revision == '':
+        print('No locally built version found!')
+        return 1
+      print(force_head_revision)
+      return 0
 
-  if args.print_clang_version:
-    sys.stdout.write(VERSION)
+    print(PACKAGE_VERSION)
     return 0
 
-  # Don't buffer stdout, so that print statements are immediately flushed.
-  # Do this only after --print-revision has been handled, else we'll get
-  # an error message when this script is run from gn for some reason.
-  sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
-
   if args.llvm_force_head_revision:
-    # Use a real revision number rather than HEAD to make sure that the stamp
-    # file logic works.
-    CLANG_REVISION = GetSvnRevision(LLVM_REPO_URL)
-    PACKAGE_VERSION = CLANG_REVISION + '-0'
+    print('--llvm-force-head-revision can only be used for --print-revision')
+    return 1
 
-    args.force_local_build = True
-    # Don't build fuchsia runtime on ToT bots at all.
-    args.with_fuchsia = False
+  if args.clang_dir:
+    global LLVM_BUILD_DIR, STAMP_FILE
+    LLVM_BUILD_DIR = os.path.abspath(args.clang_dir)
+    STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision')
 
-  return UpdateClang(args)
+  return UpdateClang()
 
 
 if __name__ == '__main__':
diff --git a/tools/clang/traffic_annotation_extractor/README.md b/tools/clang/traffic_annotation_extractor/README.md
index 5cf984a..cfbfbee 100644
--- a/tools/clang/traffic_annotation_extractor/README.md
+++ b/tools/clang/traffic_annotation_extractor/README.md
@@ -4,14 +4,14 @@
 help on how to use.
 
 ## Build on Linux
-`tools/clang/scripts/update.py --bootstrap --force-local-build
+`tools/clang/scripts/build.py --bootstrap
    --without-android --extra-tools traffic_annotation_extractor`
 
 ## Build on Window
 1. Either open a `VS2015 x64 Native Tools Command Prompt`, or open a normal
    command prompt and run `depot_tools\win_toolchain\vs_files\
    $long_autocompleted_hash\win_sdk\bin\setenv.cmd /x64`
-2. Run `python tools/clang/scripts/update.py --bootstrap --force-local-build
+2. Run `python tools/clang/scripts/build.py --bootstrap
    --without-android --extra-tools traffic_annotation_extractor`
 
 ## Usage
@@ -57,4 +57,4 @@
   - Line 2: File path.
   - Line 3: Name of the function in which assignment is done.
   - Line 4: Line number of the assignment.
-  - Line 5: "==== ASSIGNMENT ENDS ===="
\ No newline at end of file
+  - Line 5: "==== ASSIGNMENT ENDS ===="
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index d0d32b2..f63bcd6 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -1727,6 +1727,25 @@
   <int value="4" label="Undos Dismissed (Action) (Deprecated)"/>
 </enum>
 
+<enum name="AndroidWebViewClientSafeBrowsingThreatType">
+  <int value="0" label="SAFE_BROWSING_THREAT_UNKNOWN">
+    The resource was blocked for a reason other than the ones provided here.
+  </int>
+  <int value="1" label="SAFE_BROWSING_THREAT_MALWARE">
+    The resource was blocked because it contains malware.
+  </int>
+  <int value="2" label="SAFE_BROWSING_THREAT_PHISHING">
+    The resource was blocked because it contains deceptive content.
+  </int>
+  <int value="3" label="SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE">
+    The resource was blocked because it contains unwanted software.
+  </int>
+  <int value="4" label="SAFE_BROWSING_THREAT_BILLING">
+    The resource was blocked because it may trick the user into a billing
+    agreement.
+  </int>
+</enum>
+
 <enum name="AndroidWebViewVariationsEnableState">
   <int value="0" label="DEFAULT_ENABLED"/>
   <int value="1" label="CONTROL_DISABLED"/>
@@ -16669,6 +16688,7 @@
   <int value="559" label="KerberosAddAccountsAllowed"/>
   <int value="560" label="KerberosAccounts"/>
   <int value="561" label="StickyKeysEnabled"/>
+  <int value="562" label="DockedMagnifierEnabled"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations">
@@ -32284,6 +32304,7 @@
   <int value="-2132591642" label="enable-input-view"/>
   <int value="-2131746498"
       label="AutofillUseImprovedLabelDisambiguation:enabled"/>
+  <int value="-2129940395" label="WebAssemblySimd:disabled"/>
   <int value="-2128705444" label="AssistantAppSupport:enabled"/>
   <int value="-2124839789"
       label="OmniboxUIExperimentHideSteadyStateUrlSchemeAndSubdomains:enabled"/>
@@ -32552,6 +32573,7 @@
   <int value="-1768672408" label="ChromeDuplex:disabled"/>
   <int value="-1768308156" label="OmniboxDedupeGoogleDriveURLs:enabled"/>
   <int value="-1767470652" label="out-of-process-pdf"/>
+  <int value="-1766648764" label="OmniboxShortBookmarkSuggestions:disabled"/>
   <int value="-1766129470" label="DataSaverLiteModeRebranding:disabled"/>
   <int value="-1758468685" label="DownloadHomeV2:disabled"/>
   <int value="-1755301960" label="ClearOldBrowsingData:enabled"/>
@@ -34174,6 +34196,7 @@
   <int value="728656094" label="PasswordForceSaving:disabled"/>
   <int value="730024226" label="enable-out-of-process-pdf"/>
   <int value="730750097" label="PermissionsBlacklist:disabled"/>
+  <int value="731318054" label="WebAssemblySimd:enabled"/>
   <int value="731757746" label="ArcEnableDocumentsProviderInFilesApp:disabled"/>
   <int value="731775657" label="DownloadsAutoResumptionNative:disabled"/>
   <int value="731779469" label="BlinkHeapUnifiedGarbageCollection:enabled"/>
@@ -34653,6 +34676,7 @@
   <int value="1466502102" label="DelayNavigation:disabled"/>
   <int value="1469407485" label="disable-accelerated-2d-canvas"/>
   <int value="1473838479" label="EnableVirtualKeyboardMdUi:disabled"/>
+  <int value="1473967338" label="OmniboxShortBookmarkSuggestions:enabled"/>
   <int value="1474861626" label="disable-multi-mirroring"/>
   <int value="1479248574" label="disable-voice-input"/>
   <int value="1481562816" label="disable-password-link"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index f2a1c2c..84eafb1 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -3266,6 +3266,17 @@
   </summary>
 </histogram>
 
+<histogram name="Android.WebView.onSafeBrowsingHit.ThreatType"
+    enum="AndroidWebViewClientSafeBrowsingThreatType"
+    expires_after="2020-04-24">
+  <owner>laisminchillo@chromium.org</owner>
+  <owner>timvolodine@chromium.org</owner>
+  <summary>
+    Records the WebViewClient safe browsing threat type as returned by
+    onSafeBrowsingHit callback.
+  </summary>
+</histogram>
+
 <histogram name="Android.WebView.ShouldInterceptRequest.InterceptionType"
     enum="InterceptionType" expires_after="2020-02-11">
   <owner>timvolodine@chromium.org</owner>
@@ -15441,8 +15452,9 @@
 </histogram>
 
 <histogram name="CaptivePortal.Session.DetectionResult"
-    enum="CaptivePortalStatus" expires_after="M77">
+    enum="CaptivePortalStatus" expires_after="M84">
   <owner>alemate@chromium.org</owner>
+  <owner>michaeldo@chromium.org</owner>
   <summary>
     The result of captive portal detection attempts performed in user session.
     Detection result is recorded when portal detection is completed for an
@@ -15471,7 +15483,7 @@
 </histogram>
 
 <histogram name="CaptivePortal.Session.SecureConnectionFailed"
-    enum="CaptivePortalStatus">
+    enum="CaptivePortalStatus" expires_after="M84">
   <owner>michaeldo@chromium.org</owner>
   <summary>
     The result of captive portal detection attempts performed in user session.
@@ -15481,7 +15493,7 @@
 </histogram>
 
 <histogram name="CaptivePortal.Session.TimeoutDetectionResult"
-    enum="CaptivePortalStatus">
+    enum="CaptivePortalStatus" expires_after="M84">
   <owner>michaeldo@chromium.org</owner>
   <summary>
     The result of captive portal detection attempts performed in user session.
@@ -102260,7 +102272,8 @@
   </summary>
 </histogram>
 
-<histogram name="RenderTextHarfBuzz.GetFallbackFontsTime" units="ms">
+<histogram name="RenderTextHarfBuzz.GetFallbackFontsTime" units="ms"
+    expires_after="2019-11-02">
   <owner>ccameron@chromium.org</owner>
   <owner>etienneb@chromium.org</owner>
   <summary>
@@ -102270,7 +102283,19 @@
   </summary>
 </histogram>
 
-<histogram name="RenderTextHarfBuzz.ShapeRunsWithFallbackFontsTime" units="ms">
+<histogram name="RenderTextHarfBuzz.GetFallbackFontTime" units="ms"
+    expires_after="2019-11-02">
+  <owner>ccameron@chromium.org</owner>
+  <owner>etienneb@chromium.org</owner>
+  <summary>
+    Time retrieve the prefered fallback font on the system used for
+    RenderTextHarfBuzz::ShapeRuns. Fallback font is determined based on the
+    input text and locale.
+  </summary>
+</histogram>
+
+<histogram name="RenderTextHarfBuzz.ShapeRunsWithFallbackFontsTime" units="ms"
+    expires_after="2019-11-02">
   <owner>ccameron@chromium.org</owner>
   <owner>etienneb@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 923535d..84c5a729 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -5554,6 +5554,15 @@
       Set to 1 when a user is shown a client lo-fi image in a page load.
     </summary>
   </metric>
+  <metric name="coin_flip_result">
+    <summary>
+      Set to 0 if there was no attempted preview for this page load, or the coin
+      flip holdback is disabled in this session. Set to 1 if a preview was
+      attempted and was allowed to proceed by the coin flip. Set to 2 if a
+      preview would have been attempted but was held back by the coin flip. Note
+      that a non-zero value in this field implies previews_likely.
+    </summary>
+  </metric>
   <metric name="lite_page">
     <summary>
       Set to 1 when a user is shown a lite page in page load.
@@ -5597,6 +5606,14 @@
       by the origin site (rather than the user).
     </summary>
   </metric>
+  <metric name="previews_likely">
+    <summary>
+      Set to 1 when a preview will be attempted for this page load. Otherwise
+      this is not set. This does not imply that a preview will be committed,
+      only that one will be attempted. This is set to 1 even if this page load
+      is impacted by the coin flip holdback.
+    </summary>
+  </metric>
   <metric name="resource_loading_hints">
     <summary>
       Set to 1 when a user is shown a resource loading hints based preview on a
diff --git a/tools/perf/BUILD.gn b/tools/perf/BUILD.gn
index 188a426..c9ddc30 100644
--- a/tools/perf/BUILD.gn
+++ b/tools/perf/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# Keep in sync with group("perf_without_chrome").
 group("perf") {
   testonly = true
   deps = [
@@ -53,7 +54,8 @@
   }
 }
 
-# Group for running benchmarks without building Chrome
+# Group for running benchmarks without building Chrome. Keep in sync with
+# group("perf").
 group("perf_without_chrome") {
   testonly = true
   deps = [
@@ -70,6 +72,7 @@
     # Field trial dependencies
     "//tools/json_comment_eater/",
     "//tools/json_to_struct/",
+    "//components/variations/service/generate_ui_string_overrider.py",
 
     # For blink_perf benchmarks.
     "//third_party/blink/perf_tests/",
diff --git a/tools/perf/contrib/cluster_telemetry/generic_trace.py b/tools/perf/contrib/cluster_telemetry/generic_trace.py
index 803c52a..022e1fb 100644
--- a/tools/perf/contrib/cluster_telemetry/generic_trace.py
+++ b/tools/perf/contrib/cluster_telemetry/generic_trace.py
@@ -33,7 +33,8 @@
     tab.browser.platform.tracing_controller.StartTracing(config)
 
   def ValidateAndMeasurePage(self, page, tab, results):
-    trace_data = tab.browser.platform.tracing_controller.StopTracing()
+    with tab.browser.platform.tracing_controller.StopTracing() as trace_builder:
+      trace_data = trace_builder.AsData()
     for trace in trace_data.GetTracesFor(trace_data_module.CHROME_TRACE_PART):
       for event in trace['traceEvents']:
         # We collect data from duration begin, complete, instant and count
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py
index c19d062..30f8121 100644
--- a/tools/perf/core/bot_platforms.py
+++ b/tools/perf/core/bot_platforms.py
@@ -93,7 +93,7 @@
 
   @property
   def buildbot_url(self):
-    return ('https://ci.chromium.org/buildbot/chromium.perf/%s/' %
+    return ('https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/%s' %
              urllib.quote(self._name))
 
 # Linux
@@ -143,12 +143,12 @@
 
 
 ANDROID_GO = PerfPlatform(
-    'android-go-perf', 'Android O',
+    'android-go-perf', 'Android O (gobo)',
     num_shards=19,
     benchmarks_names_to_run=_ANDROID_GO_BENCHMARK_NAMES)
 
 ANDROID_GO_WEBVIEW = PerfPlatform(
-    'android-go_webview-perf', 'Android OPM1.171019.021',
+    'android-go_webview-perf', 'Android OPM1.171019.021 (gobo)',
     num_shards=25, benchmarks_names_to_run=_ANDROID_GO_BENCHMARK_NAMES)
 
 ANDROID_NEXUS_5 = PerfPlatform(
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 6ed6550..9d03eed 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -164,6 +164,10 @@
 crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/VoiceMemos_cold_3g [ Skip ]
 crbug.com/919191 [ Nexus5X_Webview ] loading.mobile/OLX_3g [ Skip ]
 
+# Benchmark: media.desktop
+crbug.com/957977 [ Win ] media.desktop/video.html?src=crowd1080.mp4 [ Skip ]
+crbug.com/957977 [ Win ] media.desktop/video.html?src=crowd1080.webm [ Skip ]
+
 # Benchmark: oilpan_gc_times.key_silk_cases
 crbug.com/446332 [ All ] oilpan_gc_times.key_silk_cases/slide_drawer [ Skip ]
 crbug.com/507865 [ All ] oilpan_gc_times.key_silk_cases/polymer_topeka [ Skip ]
diff --git a/tools/traffic_annotation/bin/README.md b/tools/traffic_annotation/bin/README.md
index 0a43e82..efc3ce0 100644
--- a/tools/traffic_annotation/bin/README.md
+++ b/tools/traffic_annotation/bin/README.md
@@ -9,7 +9,7 @@
 # On Linux:
 ```bash
 git new-branch roll_traffic_annotation_tools
-python tools/clang/scripts/update.py --bootstrap --force-local-build \
+python tools/clang/scripts/build.py --bootstrap \
     --without-android --extra-tools traffic_annotation_extractor
 cp third_party/llvm-build/Release+Asserts/bin/traffic_annotation_extractor \
     tools/traffic_annotation/bin/linux64/
@@ -39,7 +39,7 @@
 # On Windows:
 ```bash
 git new-branch roll_traffic_annotation_tools
-python tools/clang/scripts/update.py --bootstrap --force-local-build ^
+python tools/clang/scripts/build.py --bootstrap ^
     --without-android --extra-tools traffic_annotation_extractor
 cp third_party/llvm-build/Release+Asserts/bin/traffic_annotation_extractor.exe ^
     tools/traffic_annotation/bin/win32/
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 5f7d644..7b32abc 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -235,7 +235,6 @@
  <item id="safe_browsing_module_loader" hash_code="6019475" type="0" content_hash_code="49511650" os_list="linux,windows" file_path="chrome/browser/safe_browsing/client_side_model_loader.cc"/>
  <item id="safe_browsing_v4_get_hash" hash_code="8561691" type="0" content_hash_code="132435617" os_list="linux,windows" file_path="components/safe_browsing/db/v4_get_hash_protocol_manager.cc"/>
  <item id="safe_browsing_v4_update" hash_code="82509217" type="0" content_hash_code="5247849" os_list="linux,windows" file_path="components/safe_browsing/db/v4_update_protocol_manager.cc"/>
- <item id="safe_search_url_reporter" hash_code="119677115" type="0" content_hash_code="67393078" os_list="linux,windows" file_path="chrome/browser/supervised_user/experimental/safe_search_url_reporter.cc"/>
  <item id="save_file_manager" hash_code="56275203" type="0" content_hash_code="56692339" os_list="linux,windows" file_path="content/browser/download/save_file_manager.cc"/>
  <item id="sdch_dictionary_fetch" hash_code="47152935" type="0" deprecated="2017-09-16" content_hash_code="16764294" file_path=""/>
  <item id="search_suggest_service" hash_code="57785193" type="0" content_hash_code="132247652" os_list="linux,windows" file_path="chrome/browser/search/search_suggest/search_suggest_loader_impl.cc"/>
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 3449ec7..a5ebb5f 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -3248,6 +3248,25 @@
   window->OnNameChanged();
 }
 
+void AXPlatformNodeAuraLinux::OnSubtreeCreated() {
+  DCHECK(atk_object_);
+  // We might not have a parent, in that case we don't need to send the event.
+  if (!GetParent())
+    return;
+  g_signal_emit_by_name(GetParent(), "children-changed::add",
+                        GetIndexInParent(), atk_object_);
+}
+
+void AXPlatformNodeAuraLinux::OnSubtreeWillBeDeleted() {
+  DCHECK(atk_object_);
+  // There is a chance there won't be a parent as we're in the deletion process.
+  if (!GetParent())
+    return;
+
+  g_signal_emit_by_name(GetParent(), "children-changed::remove",
+                        GetIndexInParent(), atk_object_);
+}
+
 void AXPlatformNodeAuraLinux::OnInvalidStatusChanged() {
   DCHECK(atk_object_);
   atk_object_notify_state_change(
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h
index 91016b2..8d59722 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -95,6 +95,8 @@
   void OnDescriptionChanged();
   void OnInvalidStatusChanged();
   void OnDocumentTitleChanged();
+  void OnSubtreeCreated();
+  void OnSubtreeWillBeDeleted();
 
   bool SupportsSelectionWithAtkSelection();
   bool SelectionAndFocusAreTheSame();
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 1cb3527f..d4a0a82 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -1224,6 +1224,17 @@
   return "";
 }
 
+void Window::SetOpaqueRegionsForOcclusion(
+    const std::vector<gfx::Rect>& opaque_regions_for_occlusion) {
+  // Only transparent windows should try to set opaque regions for occlusion.
+  DCHECK(transparent());
+  if (opaque_regions_for_occlusion == opaque_regions_for_occlusion_)
+    return;
+  opaque_regions_for_occlusion_ = opaque_regions_for_occlusion;
+  for (auto& observer : observers_)
+    observer.OnWindowOpaqueRegionsForOcclusionChanged(this);
+}
+
 void Window::NotifyResizeLoopStarted() {
   for (auto& observer : observers_)
     observer.OnResizeLoopStarted(this);
@@ -1275,6 +1286,19 @@
     observer.OnWindowAlphaShapeSet(this);
 }
 
+void Window::OnLayerFillsBoundsOpaquelyChanged() {
+  // Let observers know that this window's transparent status has changed.
+  // Transparent status can affect the occlusion computed for windows.
+  WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
+
+  // Non-transparent windows should not have opaque regions for occlusion set.
+  if (!transparent())
+    DCHECK(opaque_regions_for_occlusion_.empty());
+
+  for (WindowObserver& observer : observers_)
+    observer.OnWindowTransparentChanged(this);
+}
+
 void Window::OnLayerTransformed(const gfx::Transform& old_transform,
                                 ui::PropertyChangeReason reason) {
   port_->OnDidChangeTransform(old_transform, layer()->transform());
diff --git a/ui/aura/window.h b/ui/aura/window.h
index d3a4005..acd4ffb8 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -475,6 +475,35 @@
   // Returns |state| as a string. This is generally only useful for debugging.
   static const char* OcclusionStateToString(OcclusionState state);
 
+  // Sets the regions of this window to consider opaque when computing the
+  // occlusion of underneath windows. Opaque regions can only be set for a
+  // transparent() window, and cannot extend outside of the window bounds.
+  // Opaque regions are relative to the window, i.e. the top-left corner of the
+  // window is considered to be the point (0, 0). If
+  // |opaque_regions_for_occlusion| is empty, the window is considered fully
+  // transparent. Opaque regions do not affect what parts of the window are
+  // visible; they only affect occlusion tracking of underneath windows. An
+  // example use case for this is when a window is made transparent because of
+  // rounded corners, and therefore does not contribute to occlusion. But,
+  // almost all of that window could be opaque and we would want it to
+  // contribute to occlusion. Occlusion tracking can affect rendering, page
+  // behaviour, and triggering for Picture-in-picture, for example. Clients
+  // should set the opaque regions for occlusion if they have transparent
+  // regions, but want to specify that certain areas of them are completely
+  // opaque. Clients that use the window shape API should also specify their
+  // shape region as a region for occlusion, if it is opaque. The opaque regions
+  // for occlusion for a window do not affect occlusion for that window itself,
+  // only what parts of other windows that window occludes.
+  // TODO: Currently, we only support one Rect in
+  //       |opaque_regions_for_occlusion|. Supporting multiple Rects will
+  //       enable window shape based occlusion.
+  void SetOpaqueRegionsForOcclusion(
+      const std::vector<gfx::Rect>& opaque_regions_for_occlusion);
+
+  const std::vector<gfx::Rect>& opaque_regions_for_occlusion() const {
+    return opaque_regions_for_occlusion_;
+  }
+
  protected:
   // Deletes (or removes if not owned by parent) all child windows. Intended for
   // use from the destructor.
@@ -585,6 +614,7 @@
                           ui::PropertyChangeReason reason) override;
   void OnLayerOpacityChanged(ui::PropertyChangeReason reason) override;
   void OnLayerAlphaShapeChanged() override;
+  void OnLayerFillsBoundsOpaquelyChanged() override;
 
   // Overridden from ui::EventTarget:
   bool CanAcceptEvent(const ui::Event& event) override;
@@ -672,6 +702,10 @@
   std::unique_ptr<LayoutManager> layout_manager_;
   std::unique_ptr<WindowTargeter> targeter_;
 
+  // The opaque regions for occlusion for this window. See comment on
+  // |SetOpaqueRegionsForOcclusion| for documentation.
+  std::vector<gfx::Rect> opaque_regions_for_occlusion_;
+
   // Makes the window pass all events through to any windows behind it.
   ws::mojom::EventTargetingPolicy event_targeting_policy_;
 
diff --git a/ui/aura/window_observer.h b/ui/aura/window_observer.h
index 4faae35..9f312d0 100644
--- a/ui/aura/window_observer.h
+++ b/ui/aura/window_observer.h
@@ -121,6 +121,10 @@
   // Invoked when the alpha shape of the |window|'s layer is set.
   virtual void OnWindowAlphaShapeSet(Window* window) {}
 
+  // Invoked when whether |window|'s layer fills its bounds opaquely or not
+  // is changed.
+  virtual void OnWindowTransparentChanged(Window* window) {}
+
   // Invoked when |window|'s position among its siblings in the stacking order
   // has changed.
   virtual void OnWindowStackingChanged(Window* window) {}
@@ -185,6 +189,9 @@
   // called if the window is destroyed during the loop.
   virtual void OnResizeLoopEnded(Window* window) {}
 
+  // Called when the opaque regions for occlusion of |window| is changed.
+  virtual void OnWindowOpaqueRegionsForOcclusionChanged(Window* window) {}
+
  protected:
   ~WindowObserver() override;
 };
diff --git a/ui/aura/window_occlusion_tracker.cc b/ui/aura/window_occlusion_tracker.cc
index 786a301..76533e00 100644
--- a/ui/aura/window_occlusion_tracker.cc
+++ b/ui/aura/window_occlusion_tracker.cc
@@ -56,6 +56,10 @@
   return false;
 }
 
+bool WindowHasOpaqueRegionsForOcclusion(Window* window) {
+  return !window->opaque_regions_for_occlusion().empty();
+}
+
 // Returns the transform of |window| relative to its root.
 // |parent_transform_relative_to_root| is the transform of |window->parent()|
 // relative to its root.
@@ -87,6 +91,21 @@
   return transform_relative_to_root;
 }
 
+SkIRect ComputeClippedAndTransformedBounds(
+    const gfx::Rect& bounds,
+    const gfx::Transform& transform_relative_to_root,
+    const SkIRect* clipped_bounds) {
+  DCHECK(transform_relative_to_root.Preserves2dAxisAlignment());
+  gfx::RectF transformed_bounds(bounds);
+  transform_relative_to_root.TransformRect(&transformed_bounds);
+  SkIRect skirect_bounds =
+      gfx::RectToSkIRect(gfx::ToEnclosedRect(transformed_bounds));
+  // If necessary, clip the bounds.
+  if (clipped_bounds && !skirect_bounds.intersect(*clipped_bounds))
+    return SkIRect::MakeEmpty();
+  return skirect_bounds;
+}
+
 // Returns the bounds of |window| relative to its |root|.
 // |transform_relative_to_root| is the transform of |window| relative to its
 // root. If |clipped_bounds| is not null, the returned bounds are clipped by it.
@@ -95,18 +114,33 @@
     const gfx::Transform& transform_relative_to_root,
     const SkIRect* clipped_bounds,
     bool use_target_values) {
-  DCHECK(transform_relative_to_root.Preserves2dAxisAlignment());
   // Compute the unclipped bounds of |window|.
   const gfx::Rect src_bounds =
       use_target_values ? window->layer()->GetTargetBounds() : window->bounds();
-  gfx::RectF bounds(0.0f, 0.0f, static_cast<float>(src_bounds.width()),
-                    static_cast<float>(src_bounds.height()));
-  transform_relative_to_root.TransformRect(&bounds);
-  SkIRect skirect_bounds = gfx::RectToSkIRect(gfx::ToEnclosedRect(bounds));
-  // If necessary, clip the bounds.
-  if (clipped_bounds && !skirect_bounds.intersect(*clipped_bounds))
-    return SkIRect::MakeEmpty();
-  return skirect_bounds;
+  return ComputeClippedAndTransformedBounds(
+      gfx::Rect(src_bounds.size()), transform_relative_to_root, clipped_bounds);
+}
+
+// Returns the bounds that |window| should contribute to be used for occluding
+// other windows. This is different to the bounds of the window if |window|
+// has opaque regions for occlusion set. We need to use different sets of bounds
+// for computing the occlusion of a window itself versus what it should
+// contribute to occluding other windows because a translucent region should
+// not be considered to occlude other windows, but must be covered by something
+// opaque for it itself to be occluded.
+SkIRect GetOpaqueBoundsInRootWindow(
+    Window* window,
+    const gfx::Transform& transform_relative_to_root,
+    const SkIRect* clipped_bounds) {
+  DCHECK(WindowHasOpaqueRegionsForOcclusion(window));
+  // TODO: Currently, we only support one Rect in the opaque region.
+  DCHECK_EQ(1u, window->opaque_regions_for_occlusion().size());
+
+  // Don't let clients mark regions outside their window bounds as opaque.
+  gfx::Rect opaque_region = window->opaque_regions_for_occlusion()[0];
+  opaque_region.Intersect(window->bounds());
+  return ComputeClippedAndTransformedBounds(
+      opaque_region, transform_relative_to_root, clipped_bounds);
 }
 
 float GetLayerCombinedTargetOpacity(const ui::Layer* layer) {
@@ -382,20 +416,28 @@
       window, false, /* is_parent_visible */ true,
       force_visible ? SkRegion() : occluded_region_before_traversing_children);
 
-  if (!force_visible && VisibleWindowIsOpaque(window))
-    occluded_region->op(window_bounds, SkRegion::kUnion_Op);
+  if (!force_visible && VisibleWindowCanOccludeOtherWindows(window)) {
+    const SkIRect occlusion_bounds =
+        WindowHasOpaqueRegionsForOcclusion(window)
+            ? GetOpaqueBoundsInRootWindow(window, transform_relative_to_root,
+                                          clipped_bounds)
+            : window_bounds;
+    occluded_region->op(occlusion_bounds, SkRegion::kUnion_Op);
+  }
   return true;
 }
 
-bool WindowOcclusionTracker::VisibleWindowIsOpaque(Window* window) const {
+bool WindowOcclusionTracker::VisibleWindowCanOccludeOtherWindows(
+    Window* window) const {
   DCHECK(window->layer());
   const float combined_opacity =
       ShouldUseTargetValues() ? GetLayerCombinedTargetOpacity(window->layer())
                               : window->layer()->GetCombinedOpacity();
-  return !window->transparent() && WindowHasContent(window) &&
-         combined_opacity == 1.0f &&
-         // For simplicity, a shaped window is not considered opaque.
-         !WindowOrParentHasShape(window);
+  return (!window->transparent() && WindowHasContent(window) &&
+          combined_opacity == 1.0f &&
+          // For simplicity, a shaped window is not considered opaque.
+          !WindowOrParentHasShape(window)) ||
+         WindowHasOpaqueRegionsForOcclusion(window);
 }
 
 bool WindowOcclusionTracker::WindowHasContent(Window* window) const {
@@ -580,7 +622,7 @@
   return false;
 }
 
-bool WindowOcclusionTracker::WindowOrDescendantIsOpaque(
+bool WindowOcclusionTracker::WindowOrDescendantCanOccludeOtherWindows(
     Window* window,
     bool assume_parent_opaque,
     bool assume_window_opaque) const {
@@ -595,10 +637,12 @@
       WindowIsAnimated(window)) {
     return false;
   }
-  if (!window->transparent() && WindowHasContent(window))
+  if ((!window->transparent() && WindowHasContent(window)) ||
+      WindowHasOpaqueRegionsForOcclusion(window)) {
     return true;
+  }
   for (Window* child_window : window->children()) {
-    if (WindowOrDescendantIsOpaque(child_window, true))
+    if (WindowOrDescendantCanOccludeOtherWindows(child_window, true))
       return true;
   }
   return false;
@@ -618,7 +662,7 @@
 bool WindowOcclusionTracker::WindowMoveMayAffectOcclusionStates(
     Window* window) const {
   return !WindowOrParentIsAnimated(window) && !WindowIsExcluded(window) &&
-         (WindowOrDescendantIsOpaque(window) ||
+         (WindowOrDescendantCanOccludeOtherWindows(window) ||
           WindowOrDescendantIsTrackedAndVisible(window));
 }
 
@@ -768,7 +812,7 @@
 void WindowOcclusionTracker::OnWillRemoveWindow(Window* window) {
   MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(window, [=]() {
     return !WindowOrParentIsAnimated(window) &&
-           WindowOrDescendantIsOpaque(window);
+           WindowOrDescendantCanOccludeOtherWindows(window);
   });
 }
 
@@ -819,6 +863,12 @@
   });
 }
 
+void WindowOcclusionTracker::OnWindowTransparentChanged(Window* window) {
+  MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(window, [=]() {
+    return WindowOpacityChangeMayAffectOcclusionStates(window);
+  });
+}
+
 void WindowOcclusionTracker::OnWindowTransformed(
     Window* window,
     ui::PropertyChangeReason reason) {
@@ -882,6 +932,17 @@
     MaybeComputeOcclusion();
 }
 
+void WindowOcclusionTracker::OnWindowOpaqueRegionsForOcclusionChanged(
+    Window* window) {
+  // If the opaque regions for occlusion change, the occlusion state may be
+  // affected if the effective opacity of the window changes (e.g. clearing the
+  // regions for occlusion), or if their bounds change.
+  MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(window, [=]() {
+    return WindowOpacityChangeMayAffectOcclusionStates(window) ||
+           WindowMoveMayAffectOcclusionStates(window);
+  });
+}
+
 void WindowOcclusionTracker::OnOcclusionStateChanged(
     WindowTreeHost* host,
     Window::OcclusionState new_state) {
diff --git a/ui/aura/window_occlusion_tracker.h b/ui/aura/window_occlusion_tracker.h
index c6495a66..e6b3611 100644
--- a/ui/aura/window_occlusion_tracker.h
+++ b/ui/aura/window_occlusion_tracker.h
@@ -192,9 +192,10 @@
       const SkIRect* clipped_bounds,
       SkRegion* occluded_region);
 
-  // Returns true if |window| opaquely fills its bounds. |window| must be
-  // visible.
-  bool VisibleWindowIsOpaque(Window* window) const;
+  // Returns true if |window| can occlude other windows (e.g. because it is
+  // not transparent or has opaque regions for occlusion).
+  // |window| must be visible.
+  bool VisibleWindowCanOccludeOtherWindows(Window* window) const;
 
   // Returns true if |window| has content.
   bool WindowHasContent(Window* window) const;
@@ -261,14 +262,15 @@
   // |tracked_windows_| and visible.
   bool WindowOrDescendantIsTrackedAndVisible(Window* window) const;
 
-  // Returns true if |window| or one of its descendants is visible, opaquely
-  // fills its bounds and is not in |animated_windows_|. If
-  // |assume_parent_opaque| is true, the function assumes that the combined
-  // opacity of window->parent() is 1.0f. If |assume_window_opaque|, the
-  // function assumes that the opacity of |window| is 1.0f.
-  bool WindowOrDescendantIsOpaque(Window* window,
-                                  bool assume_parent_opaque = false,
-                                  bool assume_window_opaque = false) const;
+  // Returns true if |window| or one of its descendants is visible, has some
+  // opaque region and is not in |animated_windows_|. If |assume_parent_opaque|
+  // is true, the function assumes that the combined opacity of window->parent()
+  // is 1.0f. If |assume_window_opaque|, the function assumes that the opacity
+  // of |window| is 1.0f.
+  bool WindowOrDescendantCanOccludeOtherWindows(
+      Window* window,
+      bool assume_parent_opaque = false,
+      bool assume_window_opaque = false) const;
 
   // Returns true if changing the opacity or alpha state of |window| could
   // affect the occlusion state of a tracked window.
@@ -327,6 +329,7 @@
   void OnWindowOpacitySet(Window* window,
                           ui::PropertyChangeReason reason) override;
   void OnWindowAlphaShapeSet(Window* window) override;
+  void OnWindowTransparentChanged(Window* window) override;
   void OnWindowTransformed(Window* window,
                            ui::PropertyChangeReason reason) override;
   void OnWindowStackingChanged(Window* window) override;
@@ -335,6 +338,7 @@
   void OnWindowRemovingFromRootWindow(Window* window,
                                       Window* new_root) override;
   void OnWindowLayerRecreated(Window* window) override;
+  void OnWindowOpaqueRegionsForOcclusionChanged(Window* window) override;
 
   // WindowTreeHostObserver
   void OnOcclusionStateChanged(WindowTreeHost* host,
diff --git a/ui/aura/window_occlusion_tracker_unittest.cc b/ui/aura/window_occlusion_tracker_unittest.cc
index 2ab48cb7..5c8edb5 100644
--- a/ui/aura/window_occlusion_tracker_unittest.cc
+++ b/ui/aura/window_occlusion_tracker_unittest.cc
@@ -2594,4 +2594,60 @@
   EXPECT_FALSE(delegate_a->is_expecting_call());
 }
 
+TEST_F(WindowOcclusionTrackerTest,
+       SetOpaqueRegionsForOcclusionAffectsOcclusionOfOtherWindows) {
+  MockWindowDelegate* delegate_a = new MockWindowDelegate();
+  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
+  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
+  EXPECT_FALSE(delegate_a->is_expecting_call());
+
+  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
+  Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 0, 10, 10));
+  EXPECT_FALSE(delegate_a->is_expecting_call());
+
+  // Make |window_b| transparent, which should make it no longer affect
+  // |window_a|'s occlusion.
+  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
+  window_b->SetTransparent(true);
+  EXPECT_FALSE(delegate_a->is_expecting_call());
+
+  // Set the opaque regions for occlusion to fully cover |window_a|. Opaque
+  // regions for occlusion are relative to the window.
+  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
+  window_b->SetOpaqueRegionsForOcclusion({gfx::Rect(0, 0, 10, 10)});
+  EXPECT_FALSE(delegate_a->is_expecting_call());
+
+  // Setting the opaque regions for occlusion to an empty list should restore to
+  // normal behavior:
+  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
+  window_b->SetOpaqueRegionsForOcclusion({});
+  EXPECT_FALSE(delegate_a->is_expecting_call());
+}
+
+TEST_F(
+    WindowOcclusionTrackerTest,
+    SetOpaqueRegionsForOcclusionOfAWindowDoesNotAffectOcclusionOfThatWindowItself) {
+  // The opaque regions for occlusion of a window affect how that window
+  // occludes other windows, but should not affect occlusion for that window
+  // itself. This is because occluding only the opaque regions of occlusion for
+  // a window may still leave translucent parts of that window visible.
+  MockWindowDelegate* delegate_a = new MockWindowDelegate();
+  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
+  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
+  EXPECT_FALSE(delegate_a->is_expecting_call());
+
+  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
+                              SkRegion(SkIRect::MakeXYWH(5, 5, 5, 5)));
+  CreateUntrackedWindow(gfx::Rect(5, 5, 5, 5));
+  EXPECT_FALSE(delegate_a->is_expecting_call());
+
+  window_a->SetTransparent(true);
+  // Changing the opaque regions for occlusion should not affect how much
+  // |window_a| is occluded by |window_b|.
+  window_a->SetOpaqueRegionsForOcclusion({gfx::Rect(0, 0, 0, 0)});
+  window_a->SetOpaqueRegionsForOcclusion({gfx::Rect(0, 0, 1, 1)});
+  window_a->SetOpaqueRegionsForOcclusion({gfx::Rect(0, 0, 5, 5)});
+  window_a->SetOpaqueRegionsForOcclusion({});
+}
+
 }  // namespace aura
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index 2ae69f9..68637016 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -637,6 +637,9 @@
   fills_bounds_opaquely_ = fills_bounds_opaquely;
 
   cc_layer_->SetContentsOpaque(fills_bounds_opaquely);
+
+  if (delegate_)
+    delegate_->OnLayerFillsBoundsOpaquelyChanged();
 }
 
 void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely) {
diff --git a/ui/compositor/layer_delegate.cc b/ui/compositor/layer_delegate.cc
index 81b3251..8973aac 100644
--- a/ui/compositor/layer_delegate.cc
+++ b/ui/compositor/layer_delegate.cc
@@ -16,6 +16,8 @@
 
 void LayerDelegate::OnLayerAlphaShapeChanged() {}
 
+void LayerDelegate::OnLayerFillsBoundsOpaquelyChanged() {}
+
 void LayerDelegate::UpdateVisualState() {}
 
 }  // namespace ui
diff --git a/ui/compositor/layer_delegate.h b/ui/compositor/layer_delegate.h
index 19a7385..d89255f 100644
--- a/ui/compositor/layer_delegate.h
+++ b/ui/compositor/layer_delegate.h
@@ -43,6 +43,9 @@
   // Invoked when the alpha shape is set.
   virtual void OnLayerAlphaShapeChanged();
 
+  // Invoked when whether the layer fills its bounds opaquely or not changed.
+  virtual void OnLayerFillsBoundsOpaquelyChanged();
+
   // Called when it is a good opportunity for the delegate to update any visual
   // state or schedule any additional regions to be painted. Soon after this is
   // called OnPaintLayer() is called.
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index 6924840..097e287 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -576,8 +576,11 @@
 TEST(LayerStandaloneTest, ReleaseMailboxOnDestruction) {
   std::unique_ptr<Layer> layer(new Layer(LAYER_TEXTURED));
   bool callback_run = false;
+
+  constexpr gfx::Size size(64, 64);
   auto resource = viz::TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+      size, false /* is_overlay_candidate */);
   layer->SetTransferableResource(
       resource,
       viz::SingleReleaseCallback::Create(
@@ -1036,8 +1039,10 @@
   cc::Layer* before_layer = l1->cc_layer_for_testing();
 
   bool callback1_run = false;
+  constexpr gfx::Size size(64, 64);
   auto resource = viz::TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+      size, false /* is_overlay_candidate */);
   l1->SetTransferableResource(resource,
                               viz::SingleReleaseCallback::Create(base::BindOnce(
                                   ReturnMailbox, &callback1_run)),
@@ -1057,7 +1062,8 @@
 
   bool callback2_run = false;
   resource = viz::TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+      size, false /* is_overlay_candidate */);
   l1->SetTransferableResource(resource,
                               viz::SingleReleaseCallback::Create(base::BindOnce(
                                   ReturnMailbox, &callback2_run)),
@@ -1082,7 +1088,8 @@
   // Back to a texture, without changing the bounds of the layer or the texture.
   bool callback3_run = false;
   resource = viz::TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+      size, false /* is_overlay_candidate */);
   l1->SetTransferableResource(resource,
                               viz::SingleReleaseCallback::Create(base::BindOnce(
                                   ReturnMailbox, &callback3_run)),
@@ -1395,8 +1402,10 @@
       base::Unretained(&run_loop));
 
   std::unique_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR));
+  constexpr gfx::Size size(64, 64);
   auto resource = viz::TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+      size, false /* is_overlay_candidate */);
   root->SetTransferableResource(
       resource, viz::SingleReleaseCallback::Create(std::move(callback)),
       gfx::Size(10, 10));
@@ -2268,8 +2277,10 @@
 TEST_F(LayerWithDelegateTest, TransferableResourceMirroring) {
   std::unique_ptr<Layer> layer(CreateLayer(LAYER_SOLID_COLOR));
 
+  constexpr gfx::Size size(64, 64);
   auto resource = viz::TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+      size, false /* is_overlay_candidate */);
   bool release_callback_run = false;
 
   layer->SetTransferableResource(
@@ -2299,7 +2310,8 @@
   EXPECT_FALSE(mirror->has_external_content());
 
   resource = viz::TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
+      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
+      size, false /* is_overlay_candidate */);
   release_callback_run = false;
 
   // Setting a transferable resource on the source layer should set it on the
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 8aadd5fb..b81cc87 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -1801,9 +1801,16 @@
 
 #if defined(OS_WIN) || defined(OS_MACOSX)
   Font fallback_font(primary_font);
-  const base::char16* run_text = &(text[runs.front()->range.start()]);
-  if (GetFallbackFont(primary_font, run_text, runs.front()->range.length(),
-                      &fallback_font)) {
+  bool fallback_found;
+  {
+    SCOPED_UMA_HISTOGRAM_LONG_TIMER("RenderTextHarfBuzz.GetFallbackFontTime");
+    TRACE_EVENT1("ui", "RenderTextHarfBuzz::GetFallbackFont", "script",
+                 TRACE_STR_COPY(uscript_getShortName(font_params.script)));
+    const base::char16* run_text = &(text[runs.front()->range.start()]);
+    fallback_found = GetFallbackFont(
+        primary_font, run_text, runs.front()->range.length(), &fallback_font);
+  }
+  if (fallback_found) {
     preferred_fallback_family = fallback_font.GetFontName();
     internal::TextRunHarfBuzz::FontParams test_font_params = font_params;
     if (test_font_params.SetFontAndRenderParams(