diff --git a/DEPS b/DEPS
index 559c1f5..cbc6283 100644
--- a/DEPS
+++ b/DEPS
@@ -126,11 +126,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '217acf58d0d80c50854c1fd8f6684c325d8d6de6',
+  'skia_revision': '3999f1076247c1a6c602d32110d6f6f833bee70a',
   # 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': 'd24c8dd69f1c7e89553ce101272aedefdb41110d',
+  'v8_revision': '54264696b3370b3f2f590d21bfe4a911c703663f',
   # 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.
@@ -138,11 +138,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': 'c66fb571be1a1599791a6d96d4055b3b84534a14',
+  'angle_revision': '18b059506119302770424cd4d55e3e28ce1e82c0',
   # 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': 'f969488577804ce90954f93da22b83ec9ae5d1e0',
+  'swiftshader_revision': '0f34a98a206d8e0feda24b52b024a9b0988bf130',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -189,7 +189,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '51e7b1437ef6375446c1bbb7db835ad5a77be25f',
+  'catapult_revision': '64102c08496b18ca97e9ba574264f10df5ae1123',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -205,7 +205,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.
-  'feed_revision': '159a13d840ef3638205987e117f746fb12514edf',
+  'feed_revision': '3293f23ae831c666be27273fbf2a73d9b2fe7552',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling android_sdk_build-tools_version
   # and whatever else without interference from each other.
@@ -402,7 +402,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'fa005e3a713d0a24c40b88916c53d36498c9256e',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '155f278b6080ae550e8b36e9c55958f65cac33c2',
       'condition': 'checkout_ios',
   },
 
@@ -757,7 +757,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '70ce8736cbc2893abc8a5141b78a637ffaab2773',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '98a7e803523c25d355e3b62907fef55dbaba3a3b',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1296,7 +1296,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f06e184f930b7e69c94613ee2b1392d5edb0b297',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3a059915745c840d3bc9f63d19e6cdb197abe3ac',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/common/crash_reporter/crash_keys.cc b/android_webview/common/crash_reporter/crash_keys.cc
index 37d7f59a..12c4a87d 100644
--- a/android_webview/common/crash_reporter/crash_keys.cc
+++ b/android_webview/common/crash_reporter/crash_keys.cc
@@ -21,6 +21,9 @@
     kAppPackageVersionCode,
     kAndroidSdkInt,
 
+    // Java exception stack traces
+    "exception_info",
+
     // gpu
     "gpu-driver",
     "gpu-psver",
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc
index 0e5a5a6..809caaa 100644
--- a/ash/public/cpp/ash_features.cc
+++ b/ash/public/cpp/ash_features.cc
@@ -20,7 +20,7 @@
     "EnableOverviewRoundedCorners", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kLockScreenNotifications{"LockScreenNotifications",
-                                             base::FEATURE_DISABLED_BY_DEFAULT};
+                                             base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kLockScreenInlineReply{"LockScreenInlineReply",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 39ca8f18..dd45f1d5 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -3069,6 +3069,7 @@
       "android/java/src/org/chromium/base/task/TaskRunner.java",
       "android/java/src/org/chromium/base/task/TaskRunnerImpl.java",
       "android/java/src/org/chromium/base/task/TaskTraits.java",
+      "android/java/src/org/chromium/base/task/TaskTraitsExtensionDescriptor.java",
     ]
 
     annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
@@ -3146,6 +3147,7 @@
     ]
 
     java_files = [
+      "test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java",
       "test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java",
       "test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java",
       "test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java",
@@ -3250,6 +3252,7 @@
       "android/junit/src/org/chromium/base/memory/MemoryPressureMonitorTest.java",
       "android/junit/src/org/chromium/base/process_launcher/ChildConnectionAllocatorTest.java",
       "android/junit/src/org/chromium/base/process_launcher/ChildProcessConnectionTest.java",
+      "android/junit/src/org/chromium/base/task/TaskTraitsTest.java",
       "test/android/junit/src/org/chromium/base/test/SetUpStatementTest.java",
       "test/android/junit/src/org/chromium/base/test/TestListInstrumentationRunListenerTest.java",
       "test/android/junit/src/org/chromium/base/test/util/AnnotationProcessingUtilsTest.java",
diff --git a/base/android/java/src/org/chromium/base/BaseSwitches.java b/base/android/java/src/org/chromium/base/BaseSwitches.java
index fe47cdd..b0b1726 100644
--- a/base/android/java/src/org/chromium/base/BaseSwitches.java
+++ b/base/android/java/src/org/chromium/base/BaseSwitches.java
@@ -27,6 +27,9 @@
     // Default country code to be used for search engine localization.
     public static final String DEFAULT_COUNTRY_CODE_AT_INSTALL = "default-country-code";
 
+    // Enables the reached code profiler.
+    public static final String ENABLE_REACHED_CODE_PROFILER = "enable-reached-code-profiler";
+
     // Prevent instantiation.
     private BaseSwitches() {}
 }
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
index 0ee9aa9..b5a8824 100644
--- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
+++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -17,6 +17,7 @@
 import android.support.v4.content.ContextCompat;
 import android.system.Os;
 
+import org.chromium.base.BaseSwitches;
 import org.chromium.base.BuildConfig;
 import org.chromium.base.BuildInfo;
 import org.chromium.base.CommandLine;
@@ -24,6 +25,7 @@
 import org.chromium.base.FileUtils;
 import org.chromium.base.Log;
 import org.chromium.base.StreamUtil;
+import org.chromium.base.StrictModeContext;
 import org.chromium.base.SysUtils;
 import org.chromium.base.TraceEvent;
 import org.chromium.base.VisibleForTesting;
@@ -85,6 +87,9 @@
     // SharedPreferences key for "don't prefetch libraries" flag
     private static final String DONT_PREFETCH_LIBRARIES_KEY = "dont_prefetch_libraries";
 
+    // Shared preferences key for the reached code profiler.
+    private static final String REACHED_CODE_PROFILER_ENABLED_KEY = "reached_code_profiler_enabled";
+
     private static final EnumeratedHistogramSample sRelinkerCountHistogram =
             new EnumeratedHistogramSample("ChromiumAndroidLinker.RelinkerFallbackCount", 2);
 
@@ -306,6 +311,33 @@
         }
     }
 
+    /**
+     * Enables the reached code profiler. The value comes from "ReachedCodeProfiler"
+     * finch experiment, and is pushed on every run. I.e. the effect of the finch experiment
+     * lags by one run, which is the best we can do considering that the profiler has to be enabled
+     * before finch is initialized. Note that since LibraryLoader is in //base, it can't depend
+     * on ChromeFeatureList, and has to rely on external code pushing the value.
+     *
+     * @param enabled whether to enable the reached code profiler.
+     */
+    public static void setReachedCodeProfilerEnabledOnNextRuns(boolean enabled) {
+        ContextUtils.getAppSharedPreferences()
+                .edit()
+                .putBoolean(REACHED_CODE_PROFILER_ENABLED_KEY, enabled)
+                .apply();
+    }
+
+    /**
+     * @return whether to enable reached code profiler (see
+     *         setReachedCodeProfilerEnabledOnNextRuns()).
+     */
+    private static boolean isReachedCodeProfilerEnabled() {
+        try (StrictModeContext unused = StrictModeContext.allowDiskReads()) {
+            return ContextUtils.getAppSharedPreferences().getBoolean(
+                    REACHED_CODE_PROFILER_ENABLED_KEY, false);
+        }
+    }
+
     /** Prefetches the native libraries in a background thread.
      *
      * Launches an AsyncTask that, through a short-lived forked process, reads a
@@ -585,6 +617,13 @@
         }
         mLibraryProcessType = processType;
 
+        // Add a switch for the reached code profiler as late as possible since it requires a read
+        // from the shared preferences. At this point the shared preferences are usually warmed up.
+        if (mLibraryProcessType == LibraryProcessType.PROCESS_BROWSER
+                && isReachedCodeProfilerEnabled()) {
+            CommandLine.getInstance().appendSwitch(BaseSwitches.ENABLE_REACHED_CODE_PROFILER);
+        }
+
         ensureCommandLineSwitchedAlreadyLocked();
 
         if (!nativeLibraryLoaded(mLibraryProcessType)) {
diff --git a/base/android/java/src/org/chromium/base/library_loader/Linker.java b/base/android/java/src/org/chromium/base/library_loader/Linker.java
index 131ac47..4367f3e2 100644
--- a/base/android/java/src/org/chromium/base/library_loader/Linker.java
+++ b/base/android/java/src/org/chromium/base/library_loader/Linker.java
@@ -15,11 +15,8 @@
 import org.chromium.base.Log;
 import org.chromium.base.StreamUtil;
 import org.chromium.base.SysUtils;
-import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.AccessedByNative;
-import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JniIgnoreNatives;
-import org.chromium.base.annotations.MainDex;
 
 import java.util.HashMap;
 import java.util.Locale;
@@ -1076,32 +1073,6 @@
     }
 
     /**
-     * Move activity from the native thread to the main UI thread.
-     * Called from native code on its own thread. Posts a callback from
-     * the UI thread back to native code.
-     *
-     * @param opaque Opaque argument.
-     */
-    @CalledByNative
-    @MainDex
-    private static void postCallbackOnMainThread(final long opaque) {
-        ThreadUtils.postOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                nativeRunCallbackOnUiThread(opaque);
-            }
-        });
-    }
-
-    /**
-     * Native method to run callbacks on the main UI thread.
-     * Supplied by the crazy linker and called by postCallbackOnMainThread.
-     *
-     * @param opaque Opaque crazy linker arguments.
-     */
-    private static native void nativeRunCallbackOnUiThread(long opaque);
-
-    /**
      * Native method used to load a library.
      *
      * @param library Platform specific library name (e.g. libfoo.so)
diff --git a/base/android/java/src/org/chromium/base/task/PostTask.java b/base/android/java/src/org/chromium/base/task/PostTask.java
index 922051e..efc15db 100644
--- a/base/android/java/src/org/chromium/base/task/PostTask.java
+++ b/base/android/java/src/org/chromium/base/task/PostTask.java
@@ -92,7 +92,7 @@
      * @param extensionId The id associated with the TaskExecutor.
      * @param taskExecutor The TaskExecutor to be registered. Must not equal zero.
      */
-    public static void registerTaskExecutor(byte extensionId, TaskExecutor taskExecutor) {
+    public static void registerTaskExecutor(int extensionId, TaskExecutor taskExecutor) {
         synchronized (sLock) {
             assert extensionId != 0;
             assert extensionId <= TaskTraits.MAX_EXTENSION_ID;
diff --git a/base/android/java/src/org/chromium/base/task/TaskTraits.java b/base/android/java/src/org/chromium/base/task/TaskTraits.java
index 6d79592..f95ebba 100644
--- a/base/android/java/src/org/chromium/base/task/TaskTraits.java
+++ b/base/android/java/src/org/chromium/base/task/TaskTraits.java
@@ -22,9 +22,13 @@
     // Keep in sync with base::TaskTraitsExtensionStorage::kStorageSize
     public static final int EXTENSION_STORAGE_SIZE = 8;
 
-    // A convenience variable explicitly specifying the default priority
+    // Convenience variables explicitly specifying common priorities
+    public static final TaskTraits USER_BLOCKING =
+            new TaskTraits().taskPriority(TaskPriority.USER_BLOCKING);
     public static final TaskTraits USER_VISIBLE =
             new TaskTraits().taskPriority(TaskPriority.USER_VISIBLE);
+    public static final TaskTraits BEST_EFFORT =
+            new TaskTraits().taskPriority(TaskPriority.BEST_EFFORT);
 
     public TaskTraits() {}
 
@@ -75,6 +79,32 @@
         return mExtensionId != INVALID_EXTENSION_ID;
     }
 
+    /**
+     * Tries to extract the extension for the given descriptor from this traits.
+     *
+     * @return Extension instance or null if the traits do not contain the requested extension
+     */
+    public <Extension> Extension getExtension(TaskTraitsExtensionDescriptor<Extension> descriptor) {
+        if (mExtensionId == descriptor.getId()) {
+            return descriptor.fromSerializedData(mExtensionData);
+        } else {
+            return null;
+        }
+    }
+
+    public <Extension> TaskTraits withExtension(
+            TaskTraitsExtensionDescriptor<Extension> descriptor, Extension extension) {
+        int id = descriptor.getId();
+        byte[] data = descriptor.toSerializedData(extension);
+        assert id > INVALID_EXTENSION_ID && id <= MAX_EXTENSION_ID;
+        assert data.length <= EXTENSION_STORAGE_SIZE;
+
+        TaskTraits taskTraits = new TaskTraits(this);
+        taskTraits.mExtensionId = (byte) id;
+        taskTraits.mExtensionData = data;
+        return taskTraits;
+    }
+
     @Override
     public boolean equals(@Nullable Object object) {
         if (object == this) {
diff --git a/base/android/java/src/org/chromium/base/task/TaskTraitsExtensionDescriptor.java b/base/android/java/src/org/chromium/base/task/TaskTraitsExtensionDescriptor.java
new file mode 100644
index 0000000..1a38265c
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/task/TaskTraitsExtensionDescriptor.java
@@ -0,0 +1,40 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.task;
+
+/**
+ * Interface to deserialize an extension from the data contained in a {@link TaskTraits} instance by
+ * passing it to the {@link TaskTraits#getExtension} method.
+ *
+ * @param <Extension>
+ * @see TaskTraits#getExtension
+ */
+public interface TaskTraitsExtensionDescriptor<Extension> {
+    /**
+     * Used by {@link TaskTraits} to make sure that extension data can be deserialized with this
+     * descriptor.
+     *
+     * @return The id for the extension that can be deserialized by this class.
+     */
+    int getId();
+
+    /**
+     * Deserializes an extension for the data contained in {@link TaskTraits}. Caller must make sure
+     * that the data is for this extension by matching the extension id contained in the
+     * {@link TaskTraits} by comparing it to the one returned by {@link #getId}
+     *
+     * @param data serialized extension data
+     * @return Extension instance
+     */
+    Extension fromSerializedData(byte[] data);
+
+    /**
+     * Serializes an extension as data contained in {@link TaskTraits}.
+     *
+     * @param extension Extension instance
+     * @return serialized extension data
+     */
+    byte[] toSerializedData(Extension extension);
+}
diff --git a/base/android/junit/src/org/chromium/base/task/TaskTraitsTest.java b/base/android/junit/src/org/chromium/base/task/TaskTraitsTest.java
new file mode 100644
index 0000000..417f77b
--- /dev/null
+++ b/base/android/junit/src/org/chromium/base/task/TaskTraitsTest.java
@@ -0,0 +1,73 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.task;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+
+/**
+ * Tests for {@link TaskTraits}
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class TaskTraitsTest {
+    private static class FakeTaskTraitsExtensionDescriptor
+            implements TaskTraitsExtensionDescriptor<String> {
+        public static final byte ID = 1;
+
+        @Override
+        public int getId() {
+            return ID;
+        }
+
+        @Override
+        public String fromSerializedData(byte[] data) {
+            return new String(data);
+        }
+
+        @Override
+        public byte[] toSerializedData(String extension) {
+            return extension.getBytes();
+        }
+    }
+
+    private static final FakeTaskTraitsExtensionDescriptor DESC =
+            new FakeTaskTraitsExtensionDescriptor();
+
+    @Test
+    @SmallTest
+    public void testExtensionPresent() {
+        String input = "Blub";
+        TaskTraits traits = new TaskTraits(FakeTaskTraitsExtensionDescriptor.ID, input.getBytes());
+        String extension = traits.getExtension(DESC);
+        assertEquals(input, extension);
+    }
+
+    @Test
+    @SmallTest
+    public void testExtensionNotPresent() {
+        String input = "Blub";
+        TaskTraits traits = new TaskTraits((byte) 0x3, input.getBytes());
+        String extension = traits.getExtension(DESC);
+        assertNull(extension);
+    }
+
+    @Test
+    @SmallTest
+    public void testSerializeDeserialize() {
+        String input = "Blub";
+        TaskTraits traits = new TaskTraits();
+        String extension = traits.withExtension(DESC, input).getExtension(DESC);
+        assertEquals(input, extension);
+    }
+}
diff --git a/base/android/linker/linker_jni.cc b/base/android/linker/linker_jni.cc
index ba632db..9848525 100644
--- a/base/android/linker/linker_jni.cc
+++ b/base/android/linker/linker_jni.cc
@@ -145,24 +145,6 @@
   return true;
 }
 
-// Initialize a jmethodID corresponding to the static method of a given
-// |clazz|, with name |method_name| and signature |method_sig|.
-// |env| is the current JNI environment handle.
-// On success, return true and set |*method_id|.
-bool InitStaticMethodId(JNIEnv* env,
-                        jclass clazz,
-                        const char* method_name,
-                        const char* method_sig,
-                        jmethodID* method_id) {
-  *method_id = env->GetStaticMethodID(clazz, method_name, method_sig);
-  if (!*method_id) {
-    LOG_ERROR("Could not find ID for static method '%s'", method_name);
-    return false;
-  }
-  LOG_INFO("Found ID %p for static method '%s'", *method_id, method_name);
-  return true;
-}
-
 // Initialize a jfieldID corresponding to the static field of a given |clazz|,
 // with name |field_name| and signature |field_sig|.
 // |env| is the current JNI environment handle.
@@ -468,90 +450,6 @@
   return true;
 }
 
-// Class holding the Java class and method ID for the Java side Linker
-// postCallbackOnMainThread method.
-struct JavaCallbackBindings_class {
-  jclass clazz;
-  jmethodID method_id;
-
-  // Initialize an instance.
-  bool Init(JNIEnv* env, jclass linker_class) {
-    clazz = reinterpret_cast<jclass>(env->NewGlobalRef(linker_class));
-    return InitStaticMethodId(env, linker_class, "postCallbackOnMainThread",
-                              "(J)V", &method_id);
-  }
-};
-
-static JavaCallbackBindings_class s_java_callback_bindings;
-
-// Designated receiver function for callbacks from Java. Its name is known
-// to the Java side.
-// |env| is the current JNI environment handle and is ignored here.
-// |clazz| is the static class handle for org.chromium.base.Linker,
-// and is ignored here.
-// |arg| is a pointer to an allocated crazy_callback_t, deleted after use.
-JNI_GENERATOR_EXPORT void
-Java_org_chromium_base_library_1loader_Linker_nativeRunCallbackOnUiThread(
-    JNIEnv* env,
-    jclass clazz,
-    jlong arg) {
-  crazy_callback_t* callback = reinterpret_cast<crazy_callback_t*>(arg);
-
-  LOG_INFO("Called back from java with handler %p, opaque %p",
-           callback->handler, callback->opaque);
-
-  crazy_callback_run(callback);
-  delete callback;
-}
-
-// Request a callback from Java. The supplied crazy_callback_t is valid only
-// for the duration of this call, so we copy it to a newly allocated
-// crazy_callback_t and then call the Java side's postCallbackOnMainThread.
-// This will call back to to our RunCallbackOnUiThread some time
-// later on the UI thread.
-// |callback_request| is a crazy_callback_t.
-// |poster_opaque| is unused.
-// Returns true if the callback request succeeds.
-static bool PostForLaterExecution(crazy_callback_t* callback_request,
-                                  void* poster_opaque UNUSED) {
-  crazy_context_t* context = GetCrazyContext();
-
-  JavaVM* vm;
-  int minimum_jni_version;
-  crazy_context_get_java_vm(context, reinterpret_cast<void**>(&vm),
-                            &minimum_jni_version);
-
-  // Do not reuse JNIEnv from JNI_OnLoad, but retrieve our own.
-  JNIEnv* env;
-  if (JNI_OK !=
-      vm->GetEnv(reinterpret_cast<void**>(&env), minimum_jni_version)) {
-    LOG_ERROR("Could not create JNIEnv");
-    return false;
-  }
-
-  // Copy the callback; the one passed as an argument may be temporary.
-  crazy_callback_t* callback = new crazy_callback_t();
-  *callback = *callback_request;
-
-  LOG_INFO("Calling back to java with handler %p, opaque %p", callback->handler,
-           callback->opaque);
-
-  jlong arg = static_cast<jlong>(reinterpret_cast<uintptr_t>(callback));
-
-  env->CallStaticVoidMethod(s_java_callback_bindings.clazz,
-                            s_java_callback_bindings.method_id, arg);
-
-  // Back out and return false if we encounter a JNI exception.
-  if (env->ExceptionCheck() == JNI_TRUE) {
-    env->ExceptionDescribe();
-    env->ExceptionClear();
-    delete callback;
-    return false;
-  }
-
-  return true;
-}
-
 JNI_GENERATOR_EXPORT jboolean
 Java_org_chromium_base_library_1loader_Linker_nativeCreateSharedRelro(
     JNIEnv* env,
@@ -651,20 +549,10 @@
                           &linker_class))
     return false;
 
-  // Resolve and save the Java side Linker callback class and method.
-  LOG_INFO("Resolving callback bindings");
-  if (!s_java_callback_bindings.Init(env, linker_class)) {
-    return false;
-  }
-
   // Save JavaVM* handle into context.
   crazy_context_t* context = GetCrazyContext();
   crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4);
 
-  // Register the function that the crazy linker can call to post code
-  // for later execution.
-  crazy_context_set_callback_poster(context, &PostForLaterExecution, nullptr);
-
   return true;
 }
 
diff --git a/base/android/reached_code_profiler.cc b/base/android/reached_code_profiler.cc
index 0513500c..07e6d5e 100644
--- a/base/android/reached_code_profiler.cc
+++ b/base/android/reached_code_profiler.cc
@@ -13,8 +13,10 @@
 
 #include "base/android/library_loader/anchor_functions.h"
 #include "base/android/orderfile/orderfile_buildflags.h"
+#include "base/base_switches.h"
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/important_file_writer.h"
@@ -40,6 +42,19 @@
 
 namespace {
 
+#if !defined(NDEBUG) || defined(COMPONENT_BUILD)
+// Always disabled for debug builds to avoid hitting a limit of signal
+// interrupts that can get delivered into a single HANDLE_EINTR. Also
+// debugging experience would be bad if there are a lot of signals flying
+// around.
+// Always disabled for component builds because in this case the code is not
+// organized in one contiguous region which is required for the reached code
+// profiler.
+constexpr const bool kConfigurationSupported = false;
+#else
+constexpr const bool kConfigurationSupported = true;
+#endif
+
 constexpr const char kDumpToFileFlag[] = "reached-code-profiler-dump-to-file";
 
 // Enough for 1 << 29 bytes of code, 512MB.
@@ -290,20 +305,11 @@
 };
 
 bool ShouldEnableReachedCodeProfiler() {
-#if !defined(NDEBUG) || defined(COMPONENT_BUILD)
-  // Always disabled for debug builds to avoid hitting a limit of signal
-  // interrupts that can get delivered into a single HANDLE_EINTR. Also
-  // debugging experience would be bad if there are a lot of signals flying
-  // around.
-  // Always disabled for component builds because in this case the code is not
-  // organized in one contiguous region which is required for the reached code
-  // profiler.
-  return false;
-#else
-  // TODO(crbug.com/916263): this should be set up according to the finch
-  // experiment.
-  return false;
-#endif
+  if (!kConfigurationSupported)
+    return false;
+
+  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
+  return cmdline->HasSwitch(switches::kEnableReachedCodeProfiler);
 }
 
 }  // namespace
@@ -323,5 +329,9 @@
   return ReachedCodeProfiler::GetInstance()->IsEnabled();
 }
 
+bool IsReachedCodeProfilerSupported() {
+  return kConfigurationSupported;
+}
+
 }  // namespace android
 }  // namespace base
diff --git a/base/android/reached_code_profiler.h b/base/android/reached_code_profiler.h
index 8d18e09f..435600e4 100644
--- a/base/android/reached_code_profiler.h
+++ b/base/android/reached_code_profiler.h
@@ -24,6 +24,10 @@
 // Returns whether the reached code profiler is enabled.
 BASE_EXPORT bool IsReachedCodeProfilerEnabled();
 
+// Returns whether the reached code profiler can be possibly enabled for the
+// current build configuration.
+BASE_EXPORT bool IsReachedCodeProfilerSupported();
+
 }  // namespace android
 }  // namespace base
 
diff --git a/base/android/reached_code_profiler_stub.cc b/base/android/reached_code_profiler_stub.cc
index 56f0fb00..f99df5c 100644
--- a/base/android/reached_code_profiler_stub.cc
+++ b/base/android/reached_code_profiler_stub.cc
@@ -14,5 +14,9 @@
   return false;
 }
 
+bool IsReachedCodeProfilerSupported() {
+  return false;
+}
+
 }  // namespace android
 }  // namespace base
diff --git a/base/base_switches.cc b/base/base_switches.cc
index ff781a3..1567a3ea 100644
--- a/base/base_switches.cc
+++ b/base/base_switches.cc
@@ -123,6 +123,10 @@
 #endif
 
 #if defined(OS_ANDROID)
+// Enables the reached code profiler that samples all threads in all processes
+// to determine which functions are almost never executed.
+const char kEnableReachedCodeProfiler[] = "enable-reached-code-profiler";
+
 // Specifies optimization of memory layout of the native library using the
 // orderfile symbols given in base/android/library_loader/anchor_functions.h,
 // via madvise and changing the library prefetch behavior.
diff --git a/base/base_switches.h b/base/base_switches.h
index 5967c1a..49650dc 100644
--- a/base/base_switches.h
+++ b/base/base_switches.h
@@ -45,6 +45,7 @@
 #endif
 
 #if defined(OS_ANDROID)
+extern const char kEnableReachedCodeProfiler[];
 extern const char kOrderfileMemoryOptimization[];
 #endif
 
diff --git a/base/containers/any_internal.cc b/base/containers/any_internal.cc
index 0d9e77d..44411667 100644
--- a/base/containers/any_internal.cc
+++ b/base/containers/any_internal.cc
@@ -11,7 +11,7 @@
   reset();
 }
 
-void AnyInternal::reset() {
+void AnyInternal::reset() noexcept {
   if (!has_value())
     return;
 
diff --git a/base/containers/checked_iterators.h b/base/containers/checked_iterators.h
index 8b3f282b..b7eb7b4 100644
--- a/base/containers/checked_iterators.h
+++ b/base/containers/checked_iterators.h
@@ -135,18 +135,20 @@
     return current_;
   }
 
-  static bool RangesOverlap(const CheckedRandomAccessIterator& from_begin,
-                            const CheckedRandomAccessIterator& from_end,
-                            const CheckedRandomAccessIterator& to) {
-    CHECK(from_begin < from_end);
+  static bool IsRangeMoveSafe(const CheckedRandomAccessIterator& from_begin,
+                              const CheckedRandomAccessIterator& from_end,
+                              const CheckedRandomAccessIterator& to)
+      WARN_UNUSED_RESULT {
+    if (from_end < from_begin)
+      return false;
     const auto from_begin_uintptr = get_uintptr(from_begin.current_);
     const auto from_end_uintptr = get_uintptr(from_end.current_);
     const auto to_begin_uintptr = get_uintptr(to.current_);
     const auto to_end_uintptr =
         get_uintptr((to + std::distance(from_begin, from_end)).current_);
 
-    return !(to_begin_uintptr >= from_end_uintptr ||
-             to_end_uintptr <= from_begin_uintptr);
+    return to_begin_uintptr >= from_end_uintptr ||
+           to_end_uintptr <= from_begin_uintptr;
   }
 
  private:
@@ -289,18 +291,20 @@
     return current_;
   }
 
-  static bool RangesOverlap(const CheckedRandomAccessConstIterator& from_begin,
-                            const CheckedRandomAccessConstIterator& from_end,
-                            const CheckedRandomAccessConstIterator& to) {
-    CHECK(from_begin < from_end);
+  static bool IsRangeMoveSafe(
+      const CheckedRandomAccessConstIterator& from_begin,
+      const CheckedRandomAccessConstIterator& from_end,
+      const CheckedRandomAccessConstIterator& to) WARN_UNUSED_RESULT {
+    if (from_end < from_begin)
+      return false;
     const auto from_begin_uintptr = get_uintptr(from_begin.current_);
     const auto from_end_uintptr = get_uintptr(from_end.current_);
     const auto to_begin_uintptr = get_uintptr(to.current_);
     const auto to_end_uintptr =
         get_uintptr((to + std::distance(from_begin, from_end)).current_);
 
-    return !(to_begin_uintptr >= from_end_uintptr ||
-             to_end_uintptr <= from_begin_uintptr);
+    return to_begin_uintptr >= from_end_uintptr ||
+           to_end_uintptr <= from_begin_uintptr;
   }
 
  private:
diff --git a/base/containers/span_unittest.cc b/base/containers/span_unittest.cc
index 40b1afb4..1af0d3b3 100644
--- a/base/containers/span_unittest.cc
+++ b/base/containers/span_unittest.cc
@@ -1092,7 +1092,7 @@
   ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.subspan(1), "");
 }
 
-TEST(SpanTest, IteratorRangesOverlap) {
+TEST(SpanTest, IteratorIsRangeMoveSafe) {
   static constexpr int kArray[] = {1, 6, 1, 8, 0};
   const size_t kNumElements = 5;
   constexpr span<const int> span(kArray);
@@ -1102,12 +1102,12 @@
 
   // Overlapping ranges.
   for (const int dest_start_index : kOverlappingStartIndexes) {
-    EXPECT_TRUE(CheckedRandomAccessIterator<const int>::RangesOverlap(
+    EXPECT_FALSE(CheckedRandomAccessIterator<const int>::IsRangeMoveSafe(
         span.begin(), span.end(),
         CheckedRandomAccessIterator<const int>(
             span.data() + dest_start_index,
             span.data() + dest_start_index + kNumElements)));
-    EXPECT_TRUE(CheckedRandomAccessConstIterator<const int>::RangesOverlap(
+    EXPECT_FALSE(CheckedRandomAccessConstIterator<const int>::IsRangeMoveSafe(
         span.cbegin(), span.cend(),
         CheckedRandomAccessConstIterator<const int>(
             span.data() + dest_start_index,
@@ -1116,17 +1116,33 @@
 
   // Non-overlapping ranges.
   for (const int dest_start_index : kNonOverlappingStartIndexes) {
-    EXPECT_FALSE(CheckedRandomAccessIterator<const int>::RangesOverlap(
+    EXPECT_TRUE(CheckedRandomAccessIterator<const int>::IsRangeMoveSafe(
         span.begin(), span.end(),
         CheckedRandomAccessIterator<const int>(
             span.data() + dest_start_index,
             span.data() + dest_start_index + kNumElements)));
-    EXPECT_FALSE(CheckedRandomAccessConstIterator<const int>::RangesOverlap(
+    EXPECT_TRUE(CheckedRandomAccessConstIterator<const int>::IsRangeMoveSafe(
         span.cbegin(), span.cend(),
         CheckedRandomAccessConstIterator<const int>(
             span.data() + dest_start_index,
             span.data() + dest_start_index + kNumElements)));
   }
+
+  // IsRangeMoveSafe is true if the length to be moved is 0.
+  EXPECT_TRUE(CheckedRandomAccessIterator<const int>::IsRangeMoveSafe(
+      span.begin(), span.begin(),
+      CheckedRandomAccessIterator<const int>(span.data(), span.data())));
+  EXPECT_TRUE(CheckedRandomAccessConstIterator<const int>::IsRangeMoveSafe(
+      span.cbegin(), span.cbegin(),
+      CheckedRandomAccessConstIterator<const int>(span.data(), span.data())));
+
+  // IsRangeMoveSafe is false if end < begin.
+  EXPECT_FALSE(CheckedRandomAccessIterator<const int>::IsRangeMoveSafe(
+      span.end(), span.begin(),
+      CheckedRandomAccessIterator<const int>(span.data(), span.data())));
+  EXPECT_FALSE(CheckedRandomAccessConstIterator<const int>::IsRangeMoveSafe(
+      span.cend(), span.cbegin(),
+      CheckedRandomAccessConstIterator<const int>(span.data(), span.data())));
 }
 
 }  // namespace base
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc
index bb303aa..86ae3f5 100644
--- a/base/message_loop/message_loop_unittest.cc
+++ b/base/message_loop/message_loop_unittest.cc
@@ -45,6 +45,7 @@
 #include "base/process/memory.h"
 #include "base/strings/string16.h"
 #include "base/win/current_module.h"
+#include "base/win/message_window.h"
 #include "base/win/scoped_handle.h"
 #endif
 
@@ -1647,6 +1648,90 @@
   EXPECT_TRUE(run_time.is_null());
 }
 
+namespace {
+
+// When this fires (per the associated WM_TIMER firing), it posts an
+// application task to quit the native loop.
+bool QuitOnSystemTimer(UINT message,
+                       WPARAM wparam,
+                       LPARAM lparam,
+                       LRESULT* result) {
+  if (message == static_cast<UINT>(WM_TIMER)) {
+    ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                            BindOnce(&::PostQuitMessage, 0));
+  }
+  return true;
+}
+
+// When this fires (per the associated WM_TIMER firing), it posts a delayed
+// application task to quit the native loop.
+bool DelayedQuitOnSystemTimer(UINT message,
+                              WPARAM wparam,
+                              LPARAM lparam,
+                              LRESULT* result) {
+  if (message == static_cast<UINT>(WM_TIMER)) {
+    ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE, BindOnce(&::PostQuitMessage, 0),
+        TimeDelta::FromMilliseconds(10));
+  }
+  return true;
+}
+
+}  // namespace
+
+// This is a regression test for
+// https://crrev.com/c/1455266/9/base/message_loop/message_pump_win.cc#125
+// See below for the delayed task version.
+// TODO(alexclarke): This test never ends up calling
+// MessagePumpForUI::ScheduleWork().
+TEST_F(MessageLoopTest, DISABLED_PostImmediateTaskFromSystemPump) {
+  MessageLoop message_loop(MessageLoop::TYPE_UI);
+
+  RunLoop run_loop;
+
+  // A native message window to generate a system message which invokes
+  // QuitOnSystemTimer() when the native timer fires.
+  win::MessageWindow local_message_window;
+  local_message_window.Create(BindRepeating(&QuitOnSystemTimer));
+  ASSERT_TRUE(::SetTimer(local_message_window.hwnd(), 0, 20, nullptr));
+
+  // The first task will enter a native message loop. This test then verifies
+  // that the pump is able to run an immediate application task after the native
+  // pump went idle.
+  message_loop.task_runner()->PostTask(
+      FROM_HERE, BindOnce(&SubPumpFunc, run_loop.QuitClosure()));
+
+  // Test success is determined by not hanging in this Run() call.
+  run_loop.Run();
+}
+
+// This is a regression test for
+// https://crrev.com/c/1455266/9/base/message_loop/message_pump_win.cc#125 This
+// is the delayed task equivalent of the above PostImmediateTaskFromSystemPump
+// test.
+// TODO(alexclarke): This test never ends up calling
+// MessagePumpForUI::ScheduleDelayedWork().
+TEST_F(MessageLoopTest, DISABLED_PostDelayedTaskFromSystemPump) {
+  MessageLoop message_loop(MessageLoop::TYPE_UI);
+
+  RunLoop run_loop;
+
+  // A native message window to generate a system message which invokes
+  // DelayedQuitOnSystemTimer() when the native timer fires.
+  win::MessageWindow local_message_window;
+  local_message_window.Create(BindRepeating(&DelayedQuitOnSystemTimer));
+  ASSERT_TRUE(::SetTimer(local_message_window.hwnd(), 0, 20, nullptr));
+
+  // The first task will enter a native message loop. This test then verifies
+  // that the pump is able to run a delayed application task after the native
+  // pump went idle.
+  message_loop.task_runner()->PostTask(
+      FROM_HERE, BindOnce(&SubPumpFunc, run_loop.QuitClosure()));
+
+  // Test success is determined by not hanging in this Run() call.
+  run_loop.Run();
+}
+
 TEST_F(MessageLoopTest, WmQuitIsVisibleToSubPump) {
   MessageLoop message_loop(MessageLoop::TYPE_UI);
 
diff --git a/base/message_loop/message_pump.h b/base/message_loop/message_pump.h
index ebbc4e5..76c0ed2e 100644
--- a/base/message_loop/message_pump.h
+++ b/base/message_loop/message_pump.h
@@ -167,10 +167,13 @@
   virtual void ScheduleWork() = 0;
 
   // Schedule a DoDelayedWork callback to happen at the specified time,
-  // cancelling any pending DoDelayedWork callback.  This method may only be
-  // used on the thread that called Run.
-  // TODO(gab): This method is obsolete in the DoSomeWork() variant, remove it
-  // once the migration is complete.
+  // cancelling any pending DoDelayedWork callback. This method may only be used
+  // on the thread that called Run.
+  //
+  // This is mostly a no-op in the DoSomeWork() world but must still be invoked
+  // when the new |delayed_work_time| is sooner than the last one returned from
+  // DoSomeWork(). TODO(gab): Clarify this API once all pumps have been
+  // migrated.
   virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) = 0;
 
   // Sets the timer slack to the specified value.
diff --git a/base/message_loop/message_pump_unittest.cc b/base/message_loop/message_pump_unittest.cc
index 4c9d032..e579860 100644
--- a/base/message_loop/message_pump_unittest.cc
+++ b/base/message_loop/message_pump_unittest.cc
@@ -30,20 +30,28 @@
 #else
       return true;
 #endif
+
     case MessageLoopBase::Type::TYPE_UI:
 #if defined(OS_IOS)
       // iOS uses a MessagePumpDefault for UI in unit tests, ref.
       // test_support_ios.mm::CreateMessagePumpForUIForTests().
       return true;
+#elif defined(OS_WIN)
+      return true;
 #else
       // TODO(gab): Complete migration of all UI pumps to DoSomeWork() as part
       // of crbug.com/885371.
       return false;
 #endif
+
     case MessageLoopBase::Type::TYPE_IO:
+#if defined(OS_WIN)
+      return true;
+#else
       // TODO(gab): Complete migration of all IO pumps to DoSomeWork() as part
       // of crbug.com/885371.
       return false;
+#endif
 
     case MessageLoopBase::Type::TYPE_CUSTOM:
 #if defined(OS_ANDROID)
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index 9de7721..39ba8edc 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -4,19 +4,16 @@
 
 #include "base/message_loop/message_pump_win.h"
 
-#include <math.h>
-#include <stdint.h>
-
-#include <limits>
+#include <algorithm>
+#include <cstdint>
+#include <type_traits>
 
 #include "base/bind.h"
 #include "base/debug/alias.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/strings/stringprintf.h"
+#include "base/numerics/ranges.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/trace_event/trace_event.h"
-#include "base/win/current_module.h"
-#include "base/win/wrapped_window_proc.h"
 
 namespace base {
 
@@ -30,6 +27,27 @@
   MESSAGE_LOOP_PROBLEM_MAX,
 };
 
+// Returns the number of milliseconds before |next_task_time|, clamped between
+// zero and the biggest DWORD value (or INFINITE if |next_task_time.is_max()|).
+// Optionally, a recent value of Now() may be passed in to avoid resampling it.
+DWORD GetSleepTimeoutMs(TimeTicks next_task_time,
+                        TimeTicks recent_now = TimeTicks()) {
+  // Shouldn't need to sleep or install a timer when there's pending immediate
+  // work.
+  DCHECK(!next_task_time.is_null());
+
+  if (next_task_time.is_max())
+    return INFINITE;
+
+  auto now = recent_now.is_null() ? TimeTicks::Now() : recent_now;
+  auto timeout_ms = (next_task_time - now).InMillisecondsRoundedUp();
+
+  // A saturated_cast with an unsigned destination automatically clamps negative
+  // values at zero.
+  static_assert(!std::is_signed<DWORD>::value, "DWORD is unexpectedly signed");
+  return saturated_cast<DWORD>(timeout_ms);
+}
+
 }  // namespace
 
 // Message sent to get an additional time slice for pumping (processing) another
@@ -43,6 +61,8 @@
 MessagePumpWin::~MessagePumpWin() = default;
 
 void MessagePumpWin::Run(Delegate* delegate) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   RunState s;
   s.delegate = delegate;
   s.should_quit = false;
@@ -57,33 +77,13 @@
 }
 
 void MessagePumpWin::Quit() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   DCHECK(state_);
   state_->should_quit = true;
 }
 
 //-----------------------------------------------------------------------------
-// MessagePumpWin protected:
-
-int MessagePumpWin::GetCurrentDelay() const {
-  if (delayed_work_time_.is_null())
-    return -1;
-
-  // Be careful here.  TimeDelta has a precision of microseconds, but we want a
-  // value in milliseconds.  If there are 5.5ms left, should the delay be 5 or
-  // 6?  It should be 6 to avoid executing delayed work too early.
-  double timeout =
-      ceil((delayed_work_time_ - TimeTicks::Now()).InMillisecondsF());
-
-  // Range check the |timeout| while converting to an integer.  If the |timeout|
-  // is negative, then we need to run delayed work soon.  If the |timeout| is
-  // "overflowingly" large, that means a delayed task was posted with a
-  // super-long delay.
-  return timeout < 0 ? 0 :
-      (timeout > std::numeric_limits<int>::max() ?
-       std::numeric_limits<int>::max() : static_cast<int>(timeout));
-}
-
-//-----------------------------------------------------------------------------
 // MessagePumpForUI public:
 
 MessagePumpForUI::MessagePumpForUI() {
@@ -95,6 +95,9 @@
 MessagePumpForUI::~MessagePumpForUI() = default;
 
 void MessagePumpForUI::ScheduleWork() {
+  // This is the only MessagePumpForUI method which can be called outside of
+  // |bound_thread_|.
+
   bool not_scheduled = false;
   if (!work_scheduled_.compare_exchange_strong(not_scheduled, true))
     return;  // Someone else continued the pumping.
@@ -120,19 +123,42 @@
 }
 
 void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
-  delayed_work_time_ = delayed_work_time;
-  RescheduleTimer();
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  // Since this is always called from |bound_thread_|, there is almost always
+  // nothing to do as the loop is already running. When the loop becomes idle,
+  // it will typically WaitForWork() in DoRunLoop() with the timeout provided by
+  // DoSomeWork(). The only alternative to this is entering a native nested loop
+  // (e.g. modal dialog) under a ScopedNestableTaskAllower, in which case
+  // HandleWorkMessage() will be invoked when the system picks up kMsgHaveWork
+  // and it will ScheduleNativeTimer() if it's out of immediate work. However,
+  // in that alternate scenario : it's possible for a Windows native task (e.g.
+  // https://docs.microsoft.com/en-us/windows/desktop/winmsg/using-hooks) to
+  // wake the native nested loop and PostDelayedTask() to the current thread
+  // from it. This is the only case where we must install/adjust the native
+  // timer from ScheduleDelayedWork() because if we don't, the native loop will
+  // go back to sleep, unaware of the new |delayed_work_time|.
+  // TODO(gab): This could potentially be replaced by a ForegroundIdleProc hook
+  // if Windows ends up being the only platform requiring ScheduleDelayedWork().
+  if (in_native_loop_ && !work_scheduled_) {
+    // TODO(gab): Consider passing a NextWorkInfo object to ScheduleDelayedWork
+    // to take advantage of |recent_now| here too.
+    ScheduleNativeTimer({delayed_work_time, TimeTicks::Now()});
+  }
 }
 
 void MessagePumpForUI::EnableWmQuit() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
   enable_wm_quit_ = true;
 }
 
 void MessagePumpForUI::AddObserver(Observer* observer) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
   observers_.AddObserver(observer);
 }
 
 void MessagePumpForUI::RemoveObserver(Observer* observer) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
   observers_.RemoveObserver(observer);
 }
 
@@ -141,18 +167,22 @@
 
 bool MessagePumpForUI::MessageCallback(
     UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
   switch (message) {
     case kMsgHaveWork:
       HandleWorkMessage();
       break;
     case WM_TIMER:
-      HandleTimerMessage();
+      if (wparam == reinterpret_cast<UINT_PTR>(this))
+        HandleTimerMessage();
       break;
   }
   return false;
 }
 
 void MessagePumpForUI::DoRunLoop() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // IF this was just a simple PeekMessage() loop (servicing all possible work
   // queues), then Windows would try to achieve the following order according
   // to MSDN documentation about PeekMessage with no filter):
@@ -175,30 +205,37 @@
     // work, then it is a good time to consider sleeping (waiting) for more
     // work.
 
+    in_native_loop_ = false;
     state_->delegate->BeforeDoInternalWork();
+    DCHECK(!in_native_loop_);
+
     bool more_work_is_plausible = ProcessNextWindowsMessage();
+    in_native_loop_ = false;
     if (state_->should_quit)
       break;
 
-    more_work_is_plausible |= state_->delegate->DoWork();
+    Delegate::NextWorkInfo next_work_info = state_->delegate->DoSomeWork();
+    in_native_loop_ = false;
+    more_work_is_plausible |= next_work_info.is_immediate();
     if (state_->should_quit)
       break;
 
-    more_work_is_plausible |=
-        state_->delegate->DoDelayedWork(&delayed_work_time_);
-    // If we did not process any delayed work, then we can assume that our
-    // existing WM_TIMER if any will fire when delayed work should run.  We
-    // don't want to disturb that timer if it is already in flight.  However,
-    // if we did do all remaining delayed work, then lets kill the WM_TIMER.
-    if (more_work_is_plausible && delayed_work_time_.is_null())
-      KillTimer(message_window_.hwnd(), reinterpret_cast<UINT_PTR>(this));
-    if (state_->should_quit)
-      break;
+    if (installed_native_timer_) {
+      // As described in ScheduleNativeTimer(), the native timer is only
+      // installed and needed while in a nested native loop. If it is installed,
+      // it means the above work entered such a loop. Having now resumed, the
+      // native timer is no longer needed.
+      KillNativeTimer();
+    }
 
     if (more_work_is_plausible)
       continue;
 
     more_work_is_plausible = state_->delegate->DoIdleWork();
+    // DoIdleWork() shouldn't end up in native nested loops and thus shouldn't
+    // have any chance of reinstalling a native timer.
+    DCHECK(!in_native_loop_);
+    DCHECK(!installed_native_timer_);
     if (state_->should_quit)
       break;
 
@@ -207,20 +244,19 @@
 
     // WaitForWork() does some work itself, so notify the delegate of it.
     state_->delegate->BeforeDoInternalWork();
-    WaitForWork();  // Wait (sleep) until we have work to do again.
+    WaitForWork(next_work_info);
   }
 }
 
-void MessagePumpForUI::WaitForWork() {
+void MessagePumpForUI::WaitForWork(Delegate::NextWorkInfo next_work_info) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // Wait until a message is available, up to the time needed by the timer
   // manager to fire the next set of timers.
-  int delay;
   DWORD wait_flags = MWMO_INPUTAVAILABLE;
-
-  while ((delay = GetCurrentDelay()) != 0) {
-    if (delay < 0)  // Negative value means no timers waiting.
-      delay = INFINITE;
-
+  for (DWORD delay = GetSleepTimeoutMs(next_work_info.delayed_run_time,
+                                       next_work_info.recent_now);
+       delay != 0; delay = GetSleepTimeoutMs(next_work_info.delayed_run_time)) {
     // Tell the optimizer to retain these values to simplify analyzing hangs.
     base::debug::Alias(&delay);
     base::debug::Alias(&wait_flags);
@@ -260,6 +296,12 @@
 }
 
 void MessagePumpForUI::HandleWorkMessage() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  // The kMsgHaveWork message was consumed by a native loop, we must assume
+  // we're in one until DoRunLoop() gets control back.
+  in_native_loop_ = true;
+
   // If we are being called outside of the context of Run, then don't try to do
   // any work.  This could correspond to a MessageBox call or something of that
   // sort.
@@ -274,16 +316,30 @@
   // messages that may be in the Windows message queue.
   ProcessPumpReplacementMessage();
 
-  // Now give the delegate a chance to do some work.  It'll let us know if it
-  // needs to do more work.
-  if (state_->delegate->DoWork())
+  Delegate::NextWorkInfo next_work_info = state_->delegate->DoSomeWork();
+  if (next_work_info.is_immediate()) {
     ScheduleWork();
-  state_->delegate->DoDelayedWork(&delayed_work_time_);
-  RescheduleTimer();
+  } else {
+    ScheduleNativeTimer(next_work_info);
+  }
 }
 
 void MessagePumpForUI::HandleTimerMessage() {
-  KillTimer(message_window_.hwnd(), reinterpret_cast<UINT_PTR>(this));
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  // ::KillTimer doesn't remove pending WM_TIMER messages from the queue,
+  // explicitly ignore the last WM_TIMER message in that case to avoid handling
+  // work from here when DoRunLoop() is active (which could result in scheduling
+  // work from two places at once). Note: we're still fine in the event that a
+  // second native nested loop is entered before such a dead WM_TIMER message is
+  // discarded because ::SetTimer merely resets the timer if invoked twice with
+  // the same id.
+  if (!installed_native_timer_)
+    return;
+
+  // We only need to fire once per specific delay, another timer may be
+  // scheduled below but we're done with this one.
+  KillNativeTimer();
 
   // If we are being called outside of the context of Run, then don't do
   // anything.  This could correspond to a MessageBox call or something of
@@ -291,46 +347,58 @@
   if (!state_)
     return;
 
-  state_->delegate->DoDelayedWork(&delayed_work_time_);
-  RescheduleTimer();
+  Delegate::NextWorkInfo next_work_info = state_->delegate->DoSomeWork();
+  if (next_work_info.is_immediate()) {
+    ScheduleWork();
+  } else {
+    ScheduleNativeTimer(next_work_info);
+  }
 }
 
-void MessagePumpForUI::RescheduleTimer() {
-  if (delayed_work_time_.is_null())
+void MessagePumpForUI::ScheduleNativeTimer(
+    Delegate::NextWorkInfo next_work_info) {
+  DCHECK(!next_work_info.is_immediate());
+  DCHECK(in_native_loop_);
+  DCHECK(!installed_native_timer_);
+
+  if (next_work_info.delayed_run_time.is_max())
     return;
-  //
-  // We would *like* to provide high resolution timers.  Windows timers using
-  // SetTimer() have a 10ms granularity.  We have to use WM_TIMER as a wakeup
-  // mechanism because the application can enter modal windows loops where it
-  // is not running our MessageLoop; the only way to have our timers fire in
-  // these cases is to post messages there.
-  //
-  // To provide sub-10ms timers, we process timers directly from our run loop.
-  // For the common case, timers will be processed there as the run loop does
-  // its normal work.  However, we *also* set the system timer so that WM_TIMER
-  // events fire.  This mops up the case of timers not being able to work in
-  // modal message loops.  It is possible for the SetTimer to pop and have no
-  // pending timers, because they could have already been processed by the
-  // run loop itself.
-  //
-  // We use a single SetTimer corresponding to the timer that will expire
-  // soonest.  As new timers are created and destroyed, we update SetTimer.
-  // Getting a spurious SetTimer event firing is benign, as we'll just be
-  // processing an empty timer queue.
-  //
-  int delay_msec = GetCurrentDelay();
-  DCHECK_GE(delay_msec, 0);
+
+  // We do not use native Windows timers in general as they have a poor, 10ms,
+  // granularity. Instead we rely on MsgWaitForMultipleObjectsEx's
+  // high-resolution timeout to sleep without timers in WaitForWork(). However,
+  // when entering a nested native ::GetMessage() loop (e.g. native modal
+  // windows) under a ScopedNestableTaskAllower, we have to rely on a native
+  // timer when HandleWorkMessage() runs out of immediate work. Since
+  // ScopedNestableTaskAllower invokes ScheduleWork() : we are guaranteed that
+  // HandleWorkMessage() will be called after entering a nested native loop that
+  // should process application tasks. But once HandleWorkMessage() is out of
+  // immediate work, ::SetTimer() is used to guarantee we are invoked again
+  // should the next delayed task expire before the nested native loop ends. The
+  // native timer being unnecessary once we return to our DoRunLoop(), we
+  // ::KillTimer when it resumes (nested native loops should be rare so we're
+  // not worried about ::SetTimer<=>::KillTimer churn).
+  // TODO(gab): The long-standing legacy dependency on the behavior of
+  // ScopedNestableTaskAllower is unfortunate, would be nice to make this a
+  // MessagePump concept (instead of requiring impls to invoke ScheduleWork()
+  // one-way and no-op DoWork() the other way).
+
+  UINT delay_msec = strict_cast<UINT>(GetSleepTimeoutMs(
+      next_work_info.delayed_run_time, next_work_info.recent_now));
   if (delay_msec == 0) {
     ScheduleWork();
   } else {
-    if (delay_msec < USER_TIMER_MINIMUM)
-      delay_msec = USER_TIMER_MINIMUM;
+    // TODO(gab): ::SetTimer()'s documentation claims it does this for us.
+    // Consider removing this safety net.
+    delay_msec = ClampToRange(delay_msec, UINT(USER_TIMER_MINIMUM),
+                              UINT(USER_TIMER_MAXIMUM));
 
-    // Tell the optimizer to retain these values to simplify analyzing hangs.
+    // Tell the optimizer to retain the delay to simplify analyzing hangs.
     base::debug::Alias(&delay_msec);
-    // Create a WM_TIMER event that will wake us up to check for any pending
-    // timers (in case we are running within a nested, external sub-pump).
-    UINT_PTR ret = SetTimer(message_window_.hwnd(), 0, delay_msec, nullptr);
+    UINT_PTR ret =
+        ::SetTimer(message_window_.hwnd(), reinterpret_cast<UINT_PTR>(this),
+                   delay_msec, nullptr);
+    installed_native_timer_ = true;
     if (ret)
       return;
     // If we can't set timers, we are in big trouble... but cross our fingers
@@ -341,11 +409,21 @@
   }
 }
 
+void MessagePumpForUI::KillNativeTimer() {
+  DCHECK(installed_native_timer_);
+  const bool success =
+      ::KillTimer(message_window_.hwnd(), reinterpret_cast<UINT_PTR>(this));
+  DPCHECK(success);
+  installed_native_timer_ = false;
+}
+
 bool MessagePumpForUI::ProcessNextWindowsMessage() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // If there are sent messages in the queue then PeekMessage internally
   // dispatches the message and returns false. We return true in this
   // case to ensure that the message loop peeks again instead of calling
-  // MsgWaitForMultipleObjectsEx again.
+  // MsgWaitForMultipleObjectsEx.
   bool sent_messages_in_queue = false;
   DWORD queue_status = ::GetQueueStatus(QS_SENDMESSAGE);
   if (HIWORD(queue_status) & QS_SENDMESSAGE)
@@ -359,6 +437,8 @@
 }
 
 bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   TRACE_EVENT1("base,toplevel", "MessagePumpForUI::ProcessMessageHelper",
                "message", msg.message);
   if (WM_QUIT == msg.message) {
@@ -390,6 +470,8 @@
 }
 
 bool MessagePumpForUI::ProcessPumpReplacementMessage() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // When we encounter a kMsgHaveWork message, this method is called to peek and
   // process a replacement message. The goal is to make the kMsgHaveWork as non-
   // intrusive as possible, even though a continuous stream of such messages are
@@ -452,22 +534,25 @@
 }
 
 MessagePumpForIO::MessagePumpForIO() {
-  port_.Set(CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr,
-      reinterpret_cast<ULONG_PTR>(nullptr), 1));
+  port_.Set(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr,
+                                     reinterpret_cast<ULONG_PTR>(nullptr), 1));
   DCHECK(port_.IsValid());
 }
 
 MessagePumpForIO::~MessagePumpForIO() = default;
 
 void MessagePumpForIO::ScheduleWork() {
+  // This is the only MessagePumpForIO method which can be called outside of
+  // |bound_thread_|.
+
   bool not_scheduled = false;
   if (!work_scheduled_.compare_exchange_strong(not_scheduled, true))
     return;  // Someone else continued the pumping.
 
   // Make sure the MessagePump does some work for us.
-  BOOL ret = PostQueuedCompletionStatus(port_.Get(), 0,
-                                        reinterpret_cast<ULONG_PTR>(this),
-                                        reinterpret_cast<OVERLAPPED*>(this));
+  BOOL ret = ::PostQueuedCompletionStatus(port_.Get(), 0,
+                                          reinterpret_cast<ULONG_PTR>(this),
+                                          reinterpret_cast<OVERLAPPED*>(this));
   if (ret)
     return;  // Post worked perfectly.
 
@@ -479,34 +564,40 @@
 }
 
 void MessagePumpForIO::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
-  // We know that we can't be blocked right now since this method can only be
-  // called on the same thread as Run, so we only need to update our record of
-  // how long to sleep when we do sleep.
-  delayed_work_time_ = delayed_work_time;
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  // Since this is always called from |bound_thread_|, there is nothing to do as
+  // the loop is already running. It will WaitForWork() in
+  // DoRunLoop() with the correct timeout when it's out of immediate tasks.
 }
 
 HRESULT MessagePumpForIO::RegisterIOHandler(HANDLE file_handle,
                                             IOHandler* handler) {
-  HANDLE port = CreateIoCompletionPort(file_handle, port_.Get(),
-                                       reinterpret_cast<ULONG_PTR>(handler), 1);
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  HANDLE port = ::CreateIoCompletionPort(
+      file_handle, port_.Get(), reinterpret_cast<ULONG_PTR>(handler), 1);
   return (port != nullptr) ? S_OK : HRESULT_FROM_WIN32(GetLastError());
 }
 
 bool MessagePumpForIO::RegisterJobObject(HANDLE job_handle,
                                          IOHandler* handler) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   JOBOBJECT_ASSOCIATE_COMPLETION_PORT info;
   info.CompletionKey = handler;
   info.CompletionPort = port_.Get();
-  return SetInformationJobObject(job_handle,
-                                 JobObjectAssociateCompletionPortInformation,
-                                 &info,
-                                 sizeof(info)) != FALSE;
+  return ::SetInformationJobObject(job_handle,
+                                   JobObjectAssociateCompletionPortInformation,
+                                   &info, sizeof(info)) != FALSE;
 }
 
 //-----------------------------------------------------------------------------
 // MessagePumpForIO private:
 
 void MessagePumpForIO::DoRunLoop() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   for (;;) {
     // If we do any work, we may create more messages etc., and more work may
     // possibly be waiting in another task group.  When we (for example)
@@ -517,7 +608,8 @@
     // had no work, then it is a good time to consider sleeping (waiting) for
     // more work.
 
-    bool more_work_is_plausible = state_->delegate->DoWork();
+    Delegate::NextWorkInfo next_work_info = state_->delegate->DoSomeWork();
+    bool more_work_is_plausible = next_work_info.is_immediate();
     if (state_->should_quit)
       break;
 
@@ -525,11 +617,6 @@
     if (state_->should_quit)
       break;
 
-    more_work_is_plausible |=
-        state_->delegate->DoDelayedWork(&delayed_work_time_);
-    if (state_->should_quit)
-      break;
-
     if (more_work_is_plausible)
       continue;
 
@@ -540,20 +627,21 @@
     if (more_work_is_plausible)
       continue;
 
-    WaitForWork();  // Wait (sleep) until we have work to do again.
+    WaitForWork(next_work_info);
   }
 }
 
 // Wait until IO completes, up to the time needed by the timer manager to fire
 // the next set of timers.
-void MessagePumpForIO::WaitForWork() {
+void MessagePumpForIO::WaitForWork(Delegate::NextWorkInfo next_work_info) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // We do not support nested IO message loops. This is to avoid messy
   // recursion problems.
   DCHECK_EQ(1, state_->run_depth) << "Cannot nest an IO message loop!";
 
-  int timeout = GetCurrentDelay();
-  if (timeout < 0)  // Negative value means no timers waiting.
-    timeout = INFINITE;
+  DWORD timeout = GetSleepTimeoutMs(next_work_info.delayed_run_time,
+                                    next_work_info.recent_now);
 
   // Tell the optimizer to retain these values to simplify analyzing hangs.
   base::debug::Alias(&timeout);
@@ -561,6 +649,8 @@
 }
 
 bool MessagePumpForIO::WaitForIOCompletion(DWORD timeout, IOHandler* filter) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   IOItem item;
   if (completed_io_.empty() || !MatchCompletedIOItem(filter, &item)) {
     // We have to ask the system for another IO completion.
@@ -583,11 +673,13 @@
 
 // Asks the OS for another IO completion result.
 bool MessagePumpForIO::GetIOItem(DWORD timeout, IOItem* item) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   memset(item, 0, sizeof(*item));
   ULONG_PTR key = reinterpret_cast<ULONG_PTR>(nullptr);
   OVERLAPPED* overlapped = nullptr;
-  if (!GetQueuedCompletionStatus(port_.Get(), &item->bytes_transfered, &key,
-                                 &overlapped, timeout)) {
+  if (!::GetQueuedCompletionStatus(port_.Get(), &item->bytes_transfered, &key,
+                                   &overlapped, timeout)) {
     if (!overlapped)
       return false;  // Nothing in the queue.
     item->error = GetLastError();
@@ -600,6 +692,8 @@
 }
 
 bool MessagePumpForIO::ProcessInternalIOItem(const IOItem& item) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   if (reinterpret_cast<void*>(this) == reinterpret_cast<void*>(item.context) &&
       reinterpret_cast<void*>(this) == reinterpret_cast<void*>(item.handler)) {
     // This is our internal completion.
@@ -612,6 +706,8 @@
 
 // Returns a completion item that was previously received.
 bool MessagePumpForIO::MatchCompletedIOItem(IOHandler* filter, IOItem* item) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   DCHECK(!completed_io_.empty());
   for (std::list<IOItem>::iterator it = completed_io_.begin();
        it != completed_io_.end(); ++it) {
diff --git a/base/message_loop/message_pump_win.h b/base/message_loop/message_pump_win.h
index e9db712..018a7c0 100644
--- a/base/message_loop/message_pump_win.h
+++ b/base/message_loop/message_pump_win.h
@@ -14,6 +14,7 @@
 #include "base/base_export.h"
 #include "base/message_loop/message_pump.h"
 #include "base/observer_list.h"
+#include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "base/win/message_window.h"
 #include "base/win/scoped_handle.h"
@@ -44,10 +45,6 @@
   };
 
   virtual void DoRunLoop() = 0;
-  int GetCurrentDelay() const;
-
-  // The time at which delayed work should run.
-  TimeTicks delayed_work_time_;
 
   // True iff:
   //   * MessagePumpForUI: there's a kMsgDoWork message pending in the Windows
@@ -74,6 +71,8 @@
 
   // State for the current invocation of Run.
   RunState* state_ = nullptr;
+
+  THREAD_CHECKER(bound_thread_);
 };
 
 //-----------------------------------------------------------------------------
@@ -151,10 +150,11 @@
   bool MessageCallback(
       UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result);
   void DoRunLoop() override;
-  void WaitForWork();
+  void WaitForWork(Delegate::NextWorkInfo next_work_info);
   void HandleWorkMessage();
   void HandleTimerMessage();
-  void RescheduleTimer();
+  void ScheduleNativeTimer(Delegate::NextWorkInfo next_work_info);
+  void KillNativeTimer();
   bool ProcessNextWindowsMessage();
   bool ProcessMessageHelper(const MSG& msg);
   bool ProcessPumpReplacementMessage();
@@ -165,6 +165,14 @@
   // TODO(thestig): Remove when the Cloud Print Service goes away.
   bool enable_wm_quit_ = false;
 
+  // True if inside a nested native loop and a native timer was installed.
+  bool installed_native_timer_ = false;
+
+  // This will become true when a native loop takes our kMsgHaveWork out of the
+  // system queue. It will be reset to false whenever DoRunLoop regains control.
+  // Used to decide whether ScheduleDelayedWork() should start a native timer.
+  bool in_native_loop_ = false;
+
   ObserverList<Observer>::Unchecked observers_;
 };
 
@@ -266,7 +274,7 @@
   };
 
   void DoRunLoop() override;
-  void WaitForWork();
+  void WaitForWork(Delegate::NextWorkInfo next_work_info);
   bool MatchCompletedIOItem(IOHandler* filter, IOItem* item);
   bool GetIOItem(DWORD timeout, IOItem* item);
   bool ProcessInternalIOItem(const IOItem& item);
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn
index 7c3632a..dea5aa2b 100644
--- a/base/test/BUILD.gn
+++ b/base/test/BUILD.gn
@@ -93,6 +93,7 @@
     "perf_time_logger.h",
     "power_monitor_test_base.cc",
     "power_monitor_test_base.h",
+    "reached_code_profiler_android.cc",
     "scoped_command_line.cc",
     "scoped_command_line.h",
     "scoped_environment_variable_override.cc",
@@ -435,6 +436,7 @@
     sources = [
       "android/java/src/org/chromium/base/MainReturnCodeResult.java",
       "android/java/src/org/chromium/base/MultiprocessTestClientLauncher.java",
+      "android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java",
       "android/javatests/src/org/chromium/base/test/task/TaskSchedulerTestHelpers.java",
       "android/javatests/src/org/chromium/base/test/util/UrlUtils.java",
     ]
diff --git a/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java b/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java
new file mode 100644
index 0000000..1b1a5c0e
--- /dev/null
+++ b/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.test;
+
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * Class containing only static methods for querying the status of the reached code profiler.
+ */
+@JNINamespace("base::android")
+public class ReachedCodeProfiler {
+    private ReachedCodeProfiler() {}
+
+    /**
+     * @return Whether the reached code profiler is enabled.
+     */
+    public static boolean isEnabled() {
+        return nativeIsReachedCodeProfilerEnabled();
+    }
+
+    /**
+     * @return Whether the currently used version of native library supports the reached code
+     *         profiler.
+     */
+    public static boolean isSupported() {
+        return nativeIsReachedCodeProfilerSupported();
+    }
+
+    private static native boolean nativeIsReachedCodeProfilerEnabled();
+    private static native boolean nativeIsReachedCodeProfilerSupported();
+}
diff --git a/base/test/reached_code_profiler_android.cc b/base/test/reached_code_profiler_android.cc
new file mode 100644
index 0000000..2def7fc
--- /dev/null
+++ b/base/test/reached_code_profiler_android.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 "base/android/jni_android.h"
+#include "base/android/reached_code_profiler.h"
+#include "jni/ReachedCodeProfiler_jni.h"
+
+// This file provides functions to query the state of the reached code profiler
+// from Java. It's used only for tests.
+namespace base {
+namespace android {
+
+static jboolean JNI_ReachedCodeProfiler_IsReachedCodeProfilerEnabled(
+    JNIEnv* env) {
+  return IsReachedCodeProfilerEnabled();
+}
+
+static jboolean JNI_ReachedCodeProfiler_IsReachedCodeProfilerSupported(
+    JNIEnv* env) {
+  return IsReachedCodeProfilerSupported();
+}
+
+}  // namespace android
+}  // namespace base
diff --git a/cc/paint/paint_image_unittest.cc b/cc/paint/paint_image_unittest.cc
index b0b71c2e..82793a6 100644
--- a/cc/paint/paint_image_unittest.cc
+++ b/cc/paint/paint_image_unittest.cc
@@ -113,4 +113,47 @@
                                      PaintImage::GetNextGeneratorClientId()));
 }
 
+TEST(PaintImageTest, DecodeToYuv420NoAlpha) {
+  const SkISize full_size = SkISize::Make(10, 10);
+  const SkISize uv_size = SkISize::Make(5, 5);
+  SkYUVASizeInfo yuva_size_info;
+  yuva_size_info.fSizes[SkYUVAIndex::kY_Index] = full_size;
+  yuva_size_info.fWidthBytes[SkYUVAIndex::kY_Index] =
+      base::checked_cast<size_t>(full_size.width());
+
+  yuva_size_info.fSizes[SkYUVAIndex::kU_Index] = uv_size;
+  yuva_size_info.fWidthBytes[SkYUVAIndex::kU_Index] =
+      base::checked_cast<size_t>(uv_size.width());
+
+  yuva_size_info.fSizes[SkYUVAIndex::kV_Index] = uv_size;
+  yuva_size_info.fWidthBytes[SkYUVAIndex::kV_Index] =
+      base::checked_cast<size_t>(uv_size.width());
+
+  yuva_size_info.fSizes[SkYUVAIndex::kA_Index] = SkISize::MakeEmpty();
+  yuva_size_info.fWidthBytes[SkYUVAIndex::kA_Index] = 0u;
+
+  sk_sp<FakePaintImageGenerator> yuv_generator =
+      sk_make_sp<FakePaintImageGenerator>(SkImageInfo::MakeN32Premul(full_size),
+                                          yuva_size_info);
+  PaintImage image = PaintImageBuilder::WithDefault()
+                         .set_id(PaintImage::GetNextId())
+                         .set_paint_image_generator(yuv_generator)
+                         .TakePaintImage();
+
+  std::vector<uint8_t> memory(yuva_size_info.computeTotalBytes());
+  void* planes[SkYUVASizeInfo::kMaxCount];
+  yuva_size_info.computePlanes(memory.data(), planes);
+
+  SkYUVASizeInfo image_yuv_size_info;
+  SkYUVAIndex image_plane_indices[SkYUVAIndex::kIndexCount];
+  ASSERT_TRUE(image.IsYuv(&image_yuv_size_info, image_plane_indices));
+  ASSERT_EQ(yuva_size_info, image_yuv_size_info);
+
+  image.DecodeYuv(planes, 1u /* frame_index */,
+                  PaintImage::kDefaultGeneratorClientId, yuva_size_info);
+  ASSERT_EQ(yuv_generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(yuv_generator->frames_decoded().count(1u), 1u);
+  yuv_generator->reset_frames_decoded();
+}
+
 }  // namespace cc
diff --git a/cc/test/skia_common.cc b/cc/test/skia_common.cc
index 0efdbef..3da647b 100644
--- a/cc/test/skia_common.cc
+++ b/cc/test/skia_common.cc
@@ -99,11 +99,37 @@
   return paint_image;
 }
 
+SkYUVASizeInfo GetYUV420SizeInfo(const gfx::Size& image_size, bool has_alpha) {
+  const SkISize uv_size = SkISize::Make((image_size.width() + 1) / 2,
+                                        (image_size.height() + 1) / 2);
+  const size_t uv_width = base::checked_cast<size_t>(uv_size.width());
+  SkYUVASizeInfo yuva_size_info;
+  yuva_size_info.fSizes[SkYUVAIndex::kY_Index].set(image_size.width(),
+                                                   image_size.height());
+  yuva_size_info.fWidthBytes[SkYUVAIndex::kY_Index] =
+      base::checked_cast<size_t>(image_size.width());
+  yuva_size_info.fSizes[SkYUVAIndex::kU_Index] = uv_size;
+  yuva_size_info.fWidthBytes[SkYUVAIndex::kU_Index] = uv_width;
+  yuva_size_info.fSizes[SkYUVAIndex::kV_Index] = uv_size;
+  yuva_size_info.fWidthBytes[SkYUVAIndex::kV_Index] = uv_width;
+  if (has_alpha) {
+    yuva_size_info.fSizes[SkYUVAIndex::kA_Index].set(image_size.width(),
+                                                     image_size.height());
+    yuva_size_info.fWidthBytes[SkYUVAIndex::kA_Index] =
+        base::checked_cast<size_t>(image_size.width());
+  } else {
+    yuva_size_info.fSizes[SkYUVAIndex::kA_Index] = SkISize::MakeEmpty();
+    yuva_size_info.fWidthBytes[SkYUVAIndex::kA_Index] = 0u;
+  }
+  return yuva_size_info;
+}
+
 PaintImage CreateDiscardablePaintImage(const gfx::Size& size,
                                        sk_sp<SkColorSpace> color_space,
                                        bool allocate_encoded_data,
                                        PaintImage::Id id,
-                                       SkColorType color_type) {
+                                       SkColorType color_type,
+                                       bool is_yuv) {
   if (!color_space)
     color_space = SkColorSpace::MakeSRGB();
   if (id == PaintImage::kInvalidId)
@@ -111,12 +137,22 @@
 
   SkImageInfo info = SkImageInfo::Make(size.width(), size.height(), color_type,
                                        kPremul_SkAlphaType, color_space);
+  sk_sp<PaintImageGenerator> generator;
+  if (is_yuv) {
+    // TODO(crbug.com/915972): Remove assumption of YUV420 in tests once we
+    // support other subsamplings.
+    generator = sk_make_sp<FakePaintImageGenerator>(
+        info, GetYUV420SizeInfo(size),
+        std::vector<FrameMetadata>{FrameMetadata()}, allocate_encoded_data);
+  } else {
+    generator = sk_make_sp<FakePaintImageGenerator>(
+        info, std::vector<FrameMetadata>{FrameMetadata()},
+        allocate_encoded_data);
+  }
   auto paint_image =
       PaintImageBuilder::WithDefault()
           .set_id(id)
-          .set_paint_image_generator(sk_make_sp<FakePaintImageGenerator>(
-              info, std::vector<FrameMetadata>{FrameMetadata()},
-              allocate_encoded_data))
+          .set_paint_image_generator(generator)
           // For simplicity, assume that any paint image created for testing is
           // unspecified decode mode as would be the case with most img tags on
           // the web.
diff --git a/cc/test/skia_common.h b/cc/test/skia_common.h
index 1c05275..c4e167728 100644
--- a/cc/test/skia_common.h
+++ b/cc/test/skia_common.h
@@ -42,12 +42,16 @@
 
 PaintImage CreatePaintWorkletPaintImage(scoped_refptr<PaintWorkletInput> input);
 
+SkYUVASizeInfo GetYUV420SizeInfo(const gfx::Size& image_size,
+                                 bool has_alpha = false);
+
 PaintImage CreateDiscardablePaintImage(
     const gfx::Size& size,
     sk_sp<SkColorSpace> color_space = nullptr,
     bool allocate_encoded_memory = true,
     PaintImage::Id id = PaintImage::kInvalidId,
-    SkColorType color_type = kN32_SkColorType);
+    SkColorType color_type = kN32_SkColorType,
+    bool is_yuv = false);
 
 DrawImage CreateDiscardableDrawImage(const gfx::Size& size,
                                      sk_sp<SkColorSpace> color_space,
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index bebf3fb55..d2c9ae2 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -237,8 +237,8 @@
       paint_image.GetSupportedDecodeSize(pixmap.bounds().size());
   // We can directly decode into target pixmap if we are doing an original
   // decode or we are decoding to scale without nearest neighbor filtering.
-  // Although the JPEG decoder supports decoding to scale, we have not yet
-  // implemented YUV + decoding to scale, so we skip it for YUV.
+  // TODO(crbug.com/927437): Although the JPEG decoder supports decoding to
+  // scale, we have not yet implemented YUV + decoding to scale, so we skip it.
   const bool can_directly_decode =
       is_original_decode || (!is_nearest_neighbor && !do_yuv_decode);
   if (supported_size == pixmap.bounds().size() && can_directly_decode) {
@@ -1778,16 +1778,14 @@
 
   sk_sp<SkColorSpace> color_space =
       SupportsColorSpaceConversion() ? target_color_space_ : nullptr;
-  // For RGBX decoding, sometimes color conversion happens during the decode, so
-  // |decode.image()| has the most up-to-date colorspace. For YUV this is not
-  // the case, so we look at |paint_image|.
-  // TODO(crbug.com/911246): Currently we avoid YUV decoding for images with an
-  // ICC profile, so |decoded_target_colorspace| will be nullptr in those cases.
-  SkColorSpace* decoded_target_colorspace =
-      image_data->is_yuv ? draw_image.paint_image().color_space()
-                         : image_data->decode.image()->colorSpace();
-  if (color_space &&
-      SkColorSpace::Equals(color_space.get(), decoded_target_colorspace)) {
+  // The value of |decoded_target_colorspace| takes into account the fact
+  // that we might need to ignore an embedded image color space if |color_type_|
+  // does not support color space conversions or that color conversion might
+  // have happened at decode time.
+  sk_sp<SkColorSpace> decoded_target_colorspace =
+      ColorSpaceForImageDecode(draw_image, image_data->mode);
+  if (color_space && SkColorSpace::Equals(color_space.get(),
+                                          decoded_target_colorspace.get())) {
     color_space = nullptr;
   }
 
@@ -1835,7 +1833,6 @@
     sk_sp<SkImage> uploaded_y_image = image_data->decode.y_image();
     sk_sp<SkImage> uploaded_u_image = image_data->decode.u_image();
     sk_sp<SkImage> uploaded_v_image = image_data->decode.v_image();
-
     image_data->decode.mark_used();
 
     // For kGpu, we upload and color convert (if necessary).
@@ -1848,8 +1845,6 @@
       // on image type.
       SkYUVColorSpace yuva_color_space =
           SkYUVColorSpace::kRec601_SkYUVColorSpace;
-      SkColorSpace* decoded_target_colorspace =
-          draw_image.paint_image().color_space();
 
       uploaded_y_image = uploaded_y_image->makeTextureImage(
           context_->GrContext(), nullptr /* colorspace */, image_needs_mips);
@@ -1857,14 +1852,17 @@
           context_->GrContext(), nullptr /* colorspace */, image_needs_mips);
       uploaded_v_image = uploaded_v_image->makeTextureImage(
           context_->GrContext(), nullptr /* colorspace */, image_needs_mips);
-      if (!uploaded_y_image || !uploaded_u_image || !uploaded_v_image)
+      if (!uploaded_y_image || !uploaded_u_image || !uploaded_v_image) {
+        DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
         return;
+      }
+
       size_t image_width = uploaded_y_image->width();
       size_t image_height = uploaded_y_image->height();
       uploaded_image = CreateImageFromYUVATexturesInternal(
           uploaded_y_image.get(), uploaded_u_image.get(),
           uploaded_v_image.get(), image_width, image_height, &yuva_color_space,
-          sk_ref_sp(decoded_target_colorspace));
+          color_space);
     }
 
     // At-raster may have decoded this while we were unlocked. If so, ignore our
@@ -1887,8 +1885,10 @@
     // TODO(crbug.com/740737): |uploaded_image| is sometimes null in certain
     // context-lost situations, so it is handled with an early out.
     if (!uploaded_image || !uploaded_y_image || !uploaded_u_image ||
-        !uploaded_v_image)
+        !uploaded_v_image) {
+      DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
       return;
+    }
 
     uploaded_y_image = TakeOwnershipOfSkImageBacking(
         context_->GrContext(), std::move(uploaded_y_image));
@@ -1945,7 +1945,7 @@
   // TODO(crbug.com/740737): uploaded_image is sometimes null in certain
   // context-lost situations.
   if (!uploaded_image) {
-    LOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
+    DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
     return;
   }
 
@@ -2358,6 +2358,7 @@
   auto found = persistent_cache_.Peek(image.frame_key());
   DCHECK(found != persistent_cache_.end());
   ImageData* image_data = found->second.get();
+  DCHECK(!image_data->is_yuv);
   return image_data->decode.ImageForTesting();
 }
 
@@ -2441,9 +2442,9 @@
       context_->GrContext(), *yuva_color_space, yuv_textures, indices,
       SkISize::Make(image_width, image_height), origin_temp,
       std::move(decoded_color_space));
-
   if (target_color_space)
     return yuva_image->makeColorSpace(target_color_space);
+
   return yuva_image;
 }
 
@@ -2485,8 +2486,10 @@
         context_->GrContext(), nullptr, GrMipMapped::kYes);
 
     // Handle lost context.
-    if (!image_y_with_mips || !image_u_with_mips || !image_v_with_mips)
+    if (!image_y_with_mips || !image_u_with_mips || !image_v_with_mips) {
+      DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
       return;
+    }
 
     // No need to do anything if mipping this image results in the same
     // textures. Deleting it below will result in lifetime issues.
@@ -2509,8 +2512,10 @@
 
     // Handle lost context
     if (!image_y_with_mips_owned || !image_u_with_mips_owned ||
-        !image_v_with_mips_owned)
+        !image_v_with_mips_owned) {
+      DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
       return;
+    }
 
     // WebP documentation says to use Rec 601 for converting to RGB.
     // TODO(crbug.com/915707): Change QueryYUVA8 to set the colorspace based
@@ -2525,8 +2530,10 @@
             image_v_with_mips_owned.get(), width, height, &yuva_color_space,
             sk_ref_sp(decoded_color_space));
     // In case of lost context
-    if (!yuv_image_with_mips_owned)
+    if (!yuv_image_with_mips_owned) {
+      DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
       return;
+    }
 
     // The previous images might be in the in-use cache, potentially held
     // externally. We must defer deleting them until the entry is unlocked.
@@ -2559,8 +2566,10 @@
       context_->GrContext(), nullptr, GrMipMapped::kYes);
 
   // Handle lost context.
-  if (!image_with_mips)
+  if (!image_with_mips) {
+    DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
     return;
+  }
 
   // No need to do anything if mipping this image results in the same texture.
   // Deleting it below will result in lifetime issues.
@@ -2572,8 +2581,10 @@
       context_->GrContext(), std::move(image_with_mips));
 
   // Handle lost context
-  if (!image_with_mips_owned)
+  if (!image_with_mips_owned) {
+    DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
     return;
+  }
 
   // The previous image might be in the in-use cache, potentially held
   // externally. We must defer deleting it until the entry is unlocked.
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc
index 224e3ab..67b92f94 100644
--- a/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -104,7 +104,7 @@
       TransferCacheTestHelper* transfer_cache_helper)
       : extension_string_(
             "GL_EXT_texture_format_BGRA8888 GL_OES_rgb8_rgba8 "
-            "GL_OES_texture_npot "
+            "GL_OES_texture_npot GL_EXT_texture_rg "
             "GL_OES_texture_half_float GL_OES_texture_half_float_linear"),
         discardable_manager_(discardable_manager),
         transfer_cache_helper_(transfer_cache_helper) {}
@@ -249,11 +249,20 @@
   return matrix;
 }
 
+#define EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE(condition) \
+  if (!use_transfer_cache_)                                \
+    EXPECT_TRUE(condition);
+
+#define EXPECT_FALSE_IF_NOT_USING_TRANSFER_CACHE(condition) \
+  if (!use_transfer_cache_)                                 \
+    EXPECT_FALSE(condition);
+
 size_t kGpuMemoryLimitBytes = 96 * 1024 * 1024;
 
 class GpuImageDecodeCacheTest
-    : public ::testing::TestWithParam<
-          std::pair<SkColorType, bool /* use_transfer_cache */>> {
+    : public ::testing::TestWithParam<std::tuple<SkColorType,
+                                                 bool /* use_transfer_cache */,
+                                                 bool /* do_yuv_decode */>> {
  public:
   void SetUp() override {
     context_provider_ = GPUImageDecodeTestMockContextProvider::Create(
@@ -268,8 +277,9 @@
       max_texture_size_ =
           context_provider_->ContextCapabilities().max_texture_size;
     }
-    use_transfer_cache_ = GetParam().second;
-    color_type_ = GetParam().first;
+    color_type_ = std::get<0>(GetParam());
+    use_transfer_cache_ = std::get<1>(GetParam());
+    do_yuv_decode_ = std::get<2>(GetParam());
   }
 
   std::unique_ptr<GpuImageDecodeCache> CreateCache() {
@@ -292,7 +302,7 @@
 
   // Returns dimensions for an image that will fit in GPU memory.
   gfx::Size GetNormalImageSize() const {
-    size_t dimension = std::min(100, max_texture_size_ - 1);
+    int dimension = std::min(100, max_texture_size_ - 1);
     return gfx::Size(dimension, dimension);
   }
 
@@ -301,11 +311,41 @@
       sk_sp<SkColorSpace> color_space = nullptr,
       PaintImage::Id id = PaintImage::kInvalidId) {
     const bool allocate_encoded_memory = true;
-    return CreateDiscardablePaintImage(
-        size, color_space, allocate_encoded_memory, id, color_type_);
+    return CreateDiscardablePaintImage(size, color_space,
+                                       allocate_encoded_memory, id, color_type_,
+                                       do_yuv_decode_);
+  }
+
+  PaintImage CreateLargePaintImageForSoftwareFallback() {
+    return CreateLargePaintImageForSoftwareFallback(GetLargeImageSize());
+  }
+
+  // Create an image that's too large to upload and will trigger falling back to
+  // software rendering and decoded data storage.
+  PaintImage CreateLargePaintImageForSoftwareFallback(
+      const gfx::Size test_image_size) {
+    CHECK(test_image_size.width() > max_texture_size_ ||
+          test_image_size.height() > max_texture_size_);
+    SkImageInfo info = SkImageInfo::Make(
+        test_image_size.width(), test_image_size.height(), color_type_,
+        kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
+    sk_sp<FakePaintImageGenerator> generator;
+    if (do_yuv_decode_) {
+      generator = sk_make_sp<FakePaintImageGenerator>(
+          info, GetYUV420SizeInfo(test_image_size));
+      generator->SetExpectFallbackToRGB();
+    } else {
+      generator = sk_make_sp<FakePaintImageGenerator>(info);
+    }
+    PaintImage image = PaintImageBuilder::WithDefault()
+                           .set_id(PaintImage::GetNextId())
+                           .set_paint_image_generator(generator)
+                           .TakePaintImage();
+    return image;
   }
 
   PaintImage CreateBitmapImageInternal(const gfx::Size& size) {
+    DCHECK(!do_yuv_decode_);
     return CreateBitmapImage(size, color_type_);
   }
 
@@ -320,10 +360,17 @@
     return context_provider_.get();
   }
 
-  void ExpectIfNotUsingTransferCache(bool value) {
-    if (!use_transfer_cache_) {
-      EXPECT_TRUE(value);
+  size_t GetBytesNeededForSingleImage(gfx::Size image_dimensions) {
+    // TODO(crbug.com/915972): Assumes YUV 420.
+    if (do_yuv_decode_) {
+      return GetYUV420SizeInfo(image_dimensions).computeTotalBytes();
     }
+    const size_t test_image_area_bytes =
+        base::checked_cast<size_t>(image_dimensions.GetArea());
+    base::CheckedNumeric<size_t> bytes_for_rgb_image_safe(
+        test_image_area_bytes);
+    bytes_for_rgb_image_safe *= SkColorTypeBytesPerPixel(color_type_);
+    return bytes_for_rgb_image_safe.ValueOrDie();
   }
 
   void SetCachedTexturesLimit(size_t limit) {
@@ -368,6 +415,7 @@
   TransferCacheTestHelper transfer_cache_helper_;
   bool use_transfer_cache_;
   SkColorType color_type_;
+  bool do_yuv_decode_;
   int max_texture_size_ = 0;
 };
 
@@ -417,12 +465,23 @@
   EXPECT_TRUE(result.need_unref);
   EXPECT_TRUE(result.task);
 
+  // |result| is an upload task which depends on a decode task.
+  EXPECT_EQ(result.task->dependencies().size(), 1u);
+  EXPECT_TRUE(result.task->dependencies()[0]);
+
   DrawImage another_draw_image(
       image, SkIRect::MakeWH(image.width(), image.height()), quality,
       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
       PaintImage::kDefaultFrameIndex);
   ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
       another_draw_image, ImageDecodeCache::TracingInfo());
+
+  // |another_draw_image| represents previous image but at a different scale.
+  // It still has one dependency (decoding), and its upload task is equivalent
+  // to the larger decoded textures being uploaded.
+  EXPECT_EQ(another_result.task->dependencies().size(), 1u);
+  EXPECT_TRUE(another_result.task->dependencies()[0]);
+
   EXPECT_TRUE(another_result.need_unref);
   EXPECT_TRUE(result.task.get() == another_result.task.get());
 
@@ -899,6 +958,8 @@
       cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
   EXPECT_TRUE(result.task);
+  EXPECT_EQ(result.task->dependencies().size(), 1u);
+  EXPECT_TRUE(result.task->dependencies()[0]);
 
   TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
   TestTileTaskRunner::ProcessTask(result.task.get());
@@ -922,7 +983,7 @@
   bool is_decomposable = true;
   SkFilterQuality quality = kHigh_SkFilterQuality;
 
-  PaintImage image = CreatePaintImageInternal(GetLargeImageSize());
+  PaintImage image = CreateLargePaintImageForSoftwareFallback();
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
@@ -943,7 +1004,7 @@
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_TRUE(decoded_draw_image.is_budgeted());
   EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked());
-  ExpectIfNotUsingTransferCache(
+  EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE(
       cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -1119,8 +1180,12 @@
       EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_TRUE(decoded_draw_image.is_budgeted());
-  EXPECT_EQ(decoded_draw_image.image()->width(), 50);
-  EXPECT_EQ(decoded_draw_image.image()->height(), 50);
+  const int expected_width =
+      image.width() * std::abs(draw_image.scale().width());
+  const int expected_height =
+      image.height() * std::abs(draw_image.scale().height());
+  EXPECT_EQ(decoded_draw_image.image()->width(), expected_width);
+  EXPECT_EQ(decoded_draw_image.image()->height(), expected_height);
   EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
@@ -1133,7 +1198,7 @@
   bool is_decomposable = true;
   SkFilterQuality quality = kHigh_SkFilterQuality;
 
-  PaintImage image = CreatePaintImageInternal(
+  PaintImage image = CreateLargePaintImageForSoftwareFallback(
       gfx::Size(GetLargeImageSize().width(), GetLargeImageSize().height() * 2));
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
@@ -1161,7 +1226,7 @@
   EXPECT_EQ(decoded_draw_image.filter_quality(), kMedium_SkFilterQuality);
 
   EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked());
-  ExpectIfNotUsingTransferCache(
+  EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE(
       cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -1173,13 +1238,14 @@
   auto cache = CreateCache();
   bool is_decomposable = true;
   SkFilterQuality quality = kHigh_SkFilterQuality;
+  const gfx::Size test_image_size = GetNormalImageSize();
 
   cache->SetWorkingSetLimitsForTesting(0 /* max_bytes */, 0 /* max_items */);
 
-  PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
+  PaintImage image = CreatePaintImageInternal(test_image_size);
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
-                       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
+                       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
                        PaintImage::kDefaultFrameIndex);
 
   ImageDecodeCache::TaskResult result =
@@ -1198,11 +1264,11 @@
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
 
-  // Increase memory limit and attempt to use the same image. It should be in
-  // available for ref.
-  size_t bytes_for_image =
-      SkColorTypeBytesPerPixel(color_type_) * image.width() * image.height();
-  cache->SetWorkingSetLimitsForTesting(bytes_for_image /* max_bytes */,
+  // Increase memory limit to allow the image and attempt to use the same image.
+  // It should be available for ref.
+  const size_t bytes_for_test_image =
+      GetBytesNeededForSingleImage(test_image_size);
+  cache->SetWorkingSetLimitsForTesting(bytes_for_test_image /* max_bytes */,
                                        256 /* max_items */);
   ImageDecodeCache::TaskResult another_result =
       cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1256,7 +1322,8 @@
   SkFilterQuality quality = kHigh_SkFilterQuality;
 
   cache->SetWorkingSetLimitsForTesting(0 /* max_bytes */, 0 /* max_items */);
-  PaintImage image = CreatePaintImageInternal(GetLargeImageSize());
+
+  PaintImage image = CreateLargePaintImageForSoftwareFallback();
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
@@ -1270,7 +1337,7 @@
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_FALSE(decoded_draw_image.is_budgeted());
   EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked());
-  ExpectIfNotUsingTransferCache(
+  EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE(
       cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -1281,7 +1348,7 @@
   EXPECT_TRUE(second_decoded_draw_image.image());
   EXPECT_FALSE(decoded_draw_image.is_budgeted());
   EXPECT_FALSE(second_decoded_draw_image.image()->isTextureBacked());
-  ExpectIfNotUsingTransferCache(
+  EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE(
       cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, second_decoded_draw_image);
@@ -1320,12 +1387,12 @@
   SkFilterQuality quality = kHigh_SkFilterQuality;
 
   PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
-  DrawImage draw_image(
-      image,
-      SkIRect::MakeXYWH(image.width() + 50, image.height() + 50, image.width(),
-                        image.height()),
-      quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      PaintImage::kDefaultFrameIndex);
+  DrawImage draw_image(image,
+                       SkIRect::MakeXYWH(image.width() + 1, image.height() + 1,
+                                         image.width(), image.height()),
+                       quality,
+                       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
+                       PaintImage::kDefaultFrameIndex);
 
   ImageDecodeCache::TaskResult result =
       cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1839,8 +1906,7 @@
   bool is_decomposable = true;
   SkFilterQuality quality = kHigh_SkFilterQuality;
 
-  // Create an image that's too large to cache.
-  PaintImage image = CreatePaintImageInternal(GetLargeImageSize());
+  PaintImage image = CreateLargePaintImageForSoftwareFallback();
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
@@ -1865,12 +1931,14 @@
       FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)),
       FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
   };
+  const gfx::Size test_image_size = GetNormalImageSize();
+  SkImageInfo info =
+      SkImageInfo::Make(test_image_size.width(), test_image_size.height(),
+                        color_type_, kPremul_SkAlphaType);
   sk_sp<FakePaintImageGenerator> generator =
-      sk_make_sp<FakePaintImageGenerator>(
-          SkImageInfo::Make(GetNormalImageSize().width(),
-                            GetNormalImageSize().height(), color_type_,
-                            kPremul_SkAlphaType),
-          frames);
+      do_yuv_decode_ ? sk_make_sp<FakePaintImageGenerator>(
+                           info, GetYUV420SizeInfo(test_image_size), frames)
+                     : sk_make_sp<FakePaintImageGenerator>(info, frames);
   PaintImage image = PaintImageBuilder::WithDefault()
                          .set_id(PaintImage::GetNextId())
                          .set_paint_image_generator(generator)
@@ -1902,8 +1970,12 @@
   cache->DrawWithImageFinished(scaled_draw_image, decoded_image);
 
   // Subset.
+  const int32_t subset_width = 5;
+  const int32_t subset_height = 5;
+  ASSERT_LT(subset_width, test_image_size.width());
+  ASSERT_LT(subset_height, test_image_size.height());
   DrawImage subset_draw_image(
-      image, SkIRect::MakeWH(5, 5), quality,
+      image, SkIRect::MakeWH(subset_width, subset_height), quality,
       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u);
   decoded_image =
       EnsureImageBacked(cache->GetDecodedImageForDraw(subset_draw_image));
@@ -1972,19 +2044,21 @@
 TEST_P(GpuImageDecodeCacheTest, AlreadyBudgetedImagesAreNotAtRaster) {
   auto cache = CreateCache();
   bool is_decomposable = true;
-  SkFilterQuality quality = kHigh_SkFilterQuality;
+  const SkFilterQuality quality = kHigh_SkFilterQuality;
+  const gfx::Size test_image_size = GetNormalImageSize();
 
-  // Allow a single small image and lock it.
-  size_t bytes_for_image = SkColorTypeBytesPerPixel(color_type_) *
-                           GetNormalImageSize().width() *
-                           GetNormalImageSize().height();
-  cache->SetWorkingSetLimitsForTesting(bytes_for_image /* max_bytes */,
-                                       1 /* max_items */);
-  PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
+  PaintImage image = CreatePaintImageInternal(test_image_size);
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
                        PaintImage::kDefaultFrameIndex);
+  const size_t bytes_for_test_image =
+      GetBytesNeededForSingleImage(test_image_size);
+
+  // Allow a single small image and lock it.
+  cache->SetWorkingSetLimitsForTesting(bytes_for_test_image,
+                                       1u /* max_items */);
+
   ImageDecodeCache::TaskResult result =
       cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -2011,16 +2085,16 @@
 TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
   auto cache = CreateCache();
   bool is_decomposable = true;
-  SkFilterQuality quality = kHigh_SkFilterQuality;
+  const SkFilterQuality quality = kHigh_SkFilterQuality;
+  const gfx::Size test_image_size = GetNormalImageSize();
 
   // Allow a single image by count. Use a high byte limit as we want to test the
   // count restriction.
-  size_t bytes_for_image = SkColorTypeBytesPerPixel(color_type_) *
-                           GetNormalImageSize().width() *
-                           GetNormalImageSize().height();
-  cache->SetWorkingSetLimitsForTesting(bytes_for_image * 100 /* max_bytes */,
-                                       1 /* max_items */);
-  PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
+  const size_t bytes_for_test_image =
+      GetBytesNeededForSingleImage(test_image_size);
+  cache->SetWorkingSetLimitsForTesting(
+      bytes_for_test_image * 100 /* max_bytes */, 1u /* max_items */);
+  PaintImage image = CreatePaintImageInternal(test_image_size);
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
@@ -2039,6 +2113,7 @@
       SkIRect::MakeWH(image.width(), image.height()), quality,
       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
       PaintImage::kDefaultFrameIndex);
+
   // Should be at raster.
   ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
@@ -2057,21 +2132,23 @@
 TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
   auto cache = CreateCache();
   bool is_decomposable = true;
-  SkFilterQuality quality = kHigh_SkFilterQuality;
+  const SkFilterQuality quality = kHigh_SkFilterQuality;
+  const gfx::Size test_image_size = GetNormalImageSize();
 
-  // Allow a single small image by size. Don't restrict the items limit as we
-  // want to test the size limit.
-  size_t bytes_for_image = SkColorTypeBytesPerPixel(color_type_) *
-                           GetNormalImageSize().width() *
-                           GetNormalImageSize().height();
-  cache->SetWorkingSetLimitsForTesting(bytes_for_image /* max_bytes */,
-                                       256 /* max_items */);
-  PaintImage image = CreateDiscardablePaintImage(GetNormalImageSize());
+  PaintImage image = CreatePaintImageInternal(test_image_size);
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
                        PaintImage::kDefaultFrameIndex);
 
+  const size_t bytes_for_test_image =
+      GetBytesNeededForSingleImage(test_image_size);
+
+  // Allow a single small image by size. Don't restrict the
+  // items limit as we want to test the size limit.
+  cache->SetWorkingSetLimitsForTesting(bytes_for_test_image,
+                                       256 /* max_items */);
+
   // The image counts against our budget.
   viz::ContextProvider::ScopedContextLock context_lock(context_provider());
   DecodedDrawImage decoded_draw_image =
@@ -2081,10 +2158,11 @@
 
   // Try another image, it shouldn't be budgeted and should be at-raster.
   DrawImage second_draw_image(
-      CreateDiscardablePaintImage(GetNormalImageSize()),
+      CreatePaintImageInternal(test_image_size),
       SkIRect::MakeWH(image.width(), image.height()), quality,
       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
       PaintImage::kDefaultFrameIndex);
+
   // Should be at raster.
   ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
@@ -2105,10 +2183,9 @@
   gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
   auto cache = CreateCache(color_space);
   bool is_decomposable = true;
-  SkFilterQuality quality = kHigh_SkFilterQuality;
+  const SkFilterQuality quality = kHigh_SkFilterQuality;
 
-  // Create an image that's too large to upload.
-  PaintImage image = CreatePaintImageInternal(GetLargeImageSize());
+  PaintImage image = CreateLargePaintImageForSoftwareFallback();
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
@@ -2161,7 +2238,7 @@
   gfx::ColorSpace color_space = gfx::ColorSpace::CreateDisplayP3D65();
   auto cache = CreateCache(color_space);
   bool is_decomposable = true;
-  SkFilterQuality quality = kHigh_SkFilterQuality;
+  const SkFilterQuality quality = kHigh_SkFilterQuality;
 
   PaintImage image = CreatePaintImageInternal(gfx::Size(11, 12));
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
@@ -2207,9 +2284,13 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScale) {
+  if (do_yuv_decode_) {
+    // YUV bitmap images do not happen, so this test will always skip for YUV.
+    return;
+  }
   auto cache = CreateCache();
   bool is_decomposable = true;
-  SkFilterQuality quality = kHigh_SkFilterQuality;
+  const SkFilterQuality quality = kHigh_SkFilterQuality;
 
   PaintImage image = CreateBitmapImageInternal(GetNormalImageSize());
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
@@ -2228,6 +2309,10 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskHasNoDeps) {
+  if (do_yuv_decode_) {
+    // YUV bitmap images do not happen, so this test will always skip for YUV.
+    return;
+  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   SkFilterQuality quality = kHigh_SkFilterQuality;
@@ -2248,6 +2333,10 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskCancelled) {
+  if (do_yuv_decode_) {
+    // YUV bitmap images do not happen, so this test will always skip for YUV.
+    return;
+  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   SkFilterQuality quality = kHigh_SkFilterQuality;
@@ -2269,6 +2358,10 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
+  if (do_yuv_decode_) {
+    // YUV bitmap images do not happen, so this test will always skip for YUV.
+    return;
+  }
   auto color_space = gfx::ColorSpace::CreateDisplayP3D65();
   auto cache = CreateCache(color_space);
   const bool should_cache_sw_image =
@@ -2299,6 +2392,10 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadDownscaled) {
+  if (do_yuv_decode_) {
+    // YUV bitmap images do not happen, so this test will always skip for YUV.
+    return;
+  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   SkFilterQuality quality = kHigh_SkFilterQuality;
@@ -2318,8 +2415,8 @@
   // cached.
   auto sw_image = cache->GetSWImageDecodeForTesting(draw_image);
   EXPECT_TRUE(sw_image);
-  EXPECT_EQ(sw_image->width(), GetNormalImageSize().width() / 2);
-  EXPECT_EQ(sw_image->height(), GetNormalImageSize().height() / 2);
+  EXPECT_EQ(sw_image->width(), (GetNormalImageSize().width() + 1) / 2);
+  EXPECT_EQ(sw_image->height(), (GetNormalImageSize().height() + 1) / 2);
 }
 
 TEST_P(GpuImageDecodeCacheTest, KeepOnlyLast2ContentIds) {
@@ -2368,20 +2465,25 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, DecodeToScale) {
+  if (do_yuv_decode_) {
+    // TODO(crbug.com/927437): Modify test after decoding to scale for YUV is
+    // implemented.
+    return;
+  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   SkFilterQuality quality = kMedium_SkFilterQuality;
 
   viz::ContextProvider::ScopedContextLock context_lock(context_provider());
-  SkISize full_size = SkISize::Make(100, 100);
-  std::vector<SkISize> supported_sizes = {SkISize::Make(25, 25),
-                                          SkISize::Make(50, 50)};
-  std::vector<FrameMetadata> frames = {FrameMetadata()};
+  const SkISize full_size = SkISize::Make(100, 100);
+  const std::vector<SkISize> supported_sizes = {SkISize::Make(25, 25),
+                                                SkISize::Make(50, 50)};
+  const std::vector<FrameMetadata> frames = {FrameMetadata()};
+  const SkImageInfo info =
+      SkImageInfo::MakeN32Premul(full_size.width(), full_size.height(),
+                                 DefaultColorSpace().ToSkColorSpace());
   sk_sp<FakePaintImageGenerator> generator =
-      sk_make_sp<FakePaintImageGenerator>(
-          SkImageInfo::MakeN32Premul(full_size.width(), full_size.height(),
-                                     DefaultColorSpace().ToSkColorSpace()),
-          frames, true, supported_sizes);
+      sk_make_sp<FakePaintImageGenerator>(info, frames, true, supported_sizes);
   PaintImage paint_image = PaintImageBuilder::WithDefault()
                                .set_id(PaintImage::GetNextId())
                                .set_paint_image_generator(generator)
@@ -2393,18 +2495,28 @@
       PaintImage::kDefaultFrameIndex);
   DecodedDrawImage decoded_image =
       EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+  const int expected_width =
+      paint_image.width() * std::abs(draw_image.scale().width());
+  const int expected_height =
+      paint_image.height() * std::abs(draw_image.scale().height());
   ASSERT_TRUE(decoded_image.image());
-  EXPECT_EQ(decoded_image.image()->width(), 50);
-  EXPECT_EQ(decoded_image.image()->height(), 50);
+  EXPECT_EQ(decoded_image.image()->width(), expected_width);
+  EXPECT_EQ(decoded_image.image()->height(), expected_height);
 
   // We should have requested a scaled decode from the generator.
   ASSERT_EQ(generator->decode_infos().size(), 1u);
-  EXPECT_EQ(generator->decode_infos().at(0).width(), 50);
-  EXPECT_EQ(generator->decode_infos().at(0).height(), 50);
+  EXPECT_EQ(generator->decode_infos().at(0).width(), expected_width);
+  EXPECT_EQ(generator->decode_infos().at(0).height(), expected_height);
+
   cache->DrawWithImageFinished(draw_image, decoded_image);
 }
 
 TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {
+  if (do_yuv_decode_) {
+    // TODO(crbug.com/927437): Modify test after decoding to scale for YUV is
+    // implemented.
+    return;
+  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   SkFilterQuality quality = kNone_SkFilterQuality;
@@ -2431,17 +2543,25 @@
   DecodedDrawImage decoded_image =
       EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
   ASSERT_TRUE(decoded_image.image());
-  EXPECT_EQ(decoded_image.image()->width(), 50);
-  EXPECT_EQ(decoded_image.image()->height(), 50);
+  const int expected_drawn_width =
+      paint_image.width() * std::abs(draw_image.scale().width());
+  const int expected_drawn_height =
+      paint_image.height() * std::abs(draw_image.scale().height());
+  EXPECT_EQ(decoded_image.image()->width(), expected_drawn_width);
+  EXPECT_EQ(decoded_image.image()->height(), expected_drawn_height);
 
   // We should have requested the original decode from the generator.
   ASSERT_EQ(generator->decode_infos().size(), 1u);
-  EXPECT_EQ(generator->decode_infos().at(0).width(), 100);
-  EXPECT_EQ(generator->decode_infos().at(0).height(), 100);
+  EXPECT_EQ(generator->decode_infos().at(0).width(), full_size.width());
+  EXPECT_EQ(generator->decode_infos().at(0).height(), full_size.height());
   cache->DrawWithImageFinished(draw_image, decoded_image);
 }
 
 TEST_P(GpuImageDecodeCacheTest, BasicMips) {
+  if (do_yuv_decode_) {
+    // We will modify this test for YUV.
+    return;
+  }
   auto decode_and_check_mips = [this](SkFilterQuality filter_quality,
                                       SkSize scale,
                                       const gfx::ColorSpace& color_space,
@@ -2502,6 +2622,10 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
+  if (do_yuv_decode_) {
+    // We will modify this test for YUV.
+    return;
+  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   auto filter_quality = kMedium_SkFilterQuality;
@@ -2576,11 +2700,15 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
+  if (do_yuv_decode_) {
+    // We will modify this test for YUV.
+    return;
+  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   auto filter_quality = kMedium_SkFilterQuality;
 
-  PaintImage image = CreateDiscardablePaintImage(GetNormalImageSize());
+  PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
 
   struct Decode {
     DrawImage image;
@@ -2666,16 +2794,67 @@
   }
 }
 
+TEST_P(GpuImageDecodeCacheTest, GetBorderlineLargeDecodedImageForDraw) {
+  // We will create a texture that's at the maximum size the GPU says it can
+  // support for uploads.
+  auto cache = CreateCache();
+  bool is_decomposable = true;
+  SkFilterQuality quality = kHigh_SkFilterQuality;
+
+  PaintImage almost_too_large_image =
+      CreatePaintImageInternal(gfx::Size(max_texture_size_, max_texture_size_));
+  DrawImage draw_image(almost_too_large_image,
+                       SkIRect::MakeWH(almost_too_large_image.width(),
+                                       almost_too_large_image.height()),
+                       quality,
+                       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+                       PaintImage::kDefaultFrameIndex);
+  ImageDecodeCache::TaskResult result =
+      cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+
+  EXPECT_TRUE(result.need_unref);
+  ASSERT_TRUE(result.task);
+  ASSERT_EQ(result.task->dependencies().size(), 1u);
+  ASSERT_TRUE(result.task->dependencies()[0]);
+
+  TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
+  TestTileTaskRunner::ProcessTask(result.task.get());
+
+  // Must hold context lock before calling GetDecodedImageForDraw /
+  // DrawWithImageFinished.
+  viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+  DecodedDrawImage decoded_draw_image =
+      EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+  EXPECT_TRUE(decoded_draw_image.image());
+  EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
+  EXPECT_TRUE(decoded_draw_image.is_budgeted());
+  EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
+
+  cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+  cache->UnrefImage(draw_image);
+}
+
+SkColorType test_color_types[] = {kN32_SkColorType, kARGB_4444_SkColorType,
+                                  kRGBA_F16_SkColorType};
+bool false_array[] = {false};
+bool true_array[] = {true};
+
 INSTANTIATE_TEST_CASE_P(
-    GpuImageDecodeCacheTests,
+    GpuImageDecodeCacheTestsInProcessRaster,
     GpuImageDecodeCacheTest,
-    ::testing::Values(
-        std::make_pair(kN32_SkColorType, false /* use_transfer_cache */),
-        std::make_pair(kARGB_4444_SkColorType, false /* use_transfer_cache */),
-        std::make_pair(kRGBA_F16_SkColorType, false /* use_transfer_cache */),
-        std::make_pair(kN32_SkColorType, true /* use_transfer_cache */),
-        std::make_pair(kARGB_4444_SkColorType, true /* use_transfer_cache */),
-        std::make_pair(kRGBA_F16_SkColorType, true /* use_transfer_cache */)));
+    testing::Combine(testing::ValuesIn(test_color_types),
+                     testing::ValuesIn(false_array) /* use_transfer_cache */,
+                     testing::Bool() /* do_yuv_decode */));
+
+INSTANTIATE_TEST_CASE_P(
+    GpuImageDecodeCacheTestsOOPR,
+    GpuImageDecodeCacheTest,
+    testing::Combine(testing::ValuesIn(test_color_types),
+                     testing::ValuesIn(true_array) /* use_transfer_cache */,
+                     testing::ValuesIn(false_array) /* do_yuv_decode */));
+
+#undef EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE
+#undef EXPECT_FALSE_IF_NOT_USING_TRANSFER_CACHE
 
 }  // namespace
 }  // namespace cc
diff --git a/cc/tiles/tile_priority.h b/cc/tiles/tile_priority.h
index 015b0c4..6b0628a 100644
--- a/cc/tiles/tile_priority.h
+++ b/cc/tiles/tile_priority.h
@@ -70,7 +70,7 @@
 
 enum TileMemoryLimitPolicy {
   // Nothing. This mode is used when visible is set to false.
-  ALLOW_NOTHING = 0,
+  ALLOW_NOTHING = 0,  // Decaf.
 
   // You might be made visible, but you're not being interacted with.
   ALLOW_ABSOLUTE_MINIMUM = 1,  // Tall.
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index 64644e3..e21cba7a 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -343,6 +343,18 @@
             android:excludeFromRecents="true"
             android:exported="false" />
 
+        <activity android:name="org.chromium.chrome.browser.incognito.IncognitoTabLauncher"
+            android:theme="@android:style/Theme.NoDisplay"
+            android:taskAffinity=""
+            android:enabled="false"
+            android:excludeFromRecents="true"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="org.chromium.chrome.browser.incognito.OPEN_PRIVATE_TAB" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <!-- Upgrade related -->
         <activity android:name="org.chromium.chrome.browser.upgrade.UpgradeActivity"
             android:excludeFromRecents="true"
diff --git a/chrome/android/java/monochrome_public_apk.AndroidManifest.expected b/chrome/android/java/monochrome_public_apk.AndroidManifest.expected
index 87621e0..6aeba47 100644
--- a/chrome/android/java/monochrome_public_apk.AndroidManifest.expected
+++ b/chrome/android/java/monochrome_public_apk.AndroidManifest.expected
@@ -889,6 +889,18 @@
       </intent-filter>
     </activity>
     <activity
+        android:enabled="false"
+        android:excludeFromRecents="true"
+        android:exported="true"
+        android:name="org.chromium.chrome.browser.incognito.IncognitoTabLauncher"
+        android:taskAffinity=""
+        android:theme="@android:style/Theme.NoDisplay">
+      <intent-filter>
+        <action android:name="org.chromium.chrome.browser.incognito.OPEN_PRIVATE_TAB"/>
+        <category android:name="android.intent.category.DEFAULT"/>
+      </intent-filter>
+    </activity>
+    <activity
         android:excludeFromRecents="true"
         android:exported="false"
         android:launchMode="singleInstance"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
index 74410f9..cc7eff3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -150,6 +150,7 @@
     }
 
     // Alphabetical:
+    public static final String ALLOW_NEW_INCOGNITO_TAB_INTENTS = "AllowNewIncognitoTabIntents";
     public static final String ALLOW_REMOTE_CONTEXT_FOR_NOTIFICATIONS =
             "AllowRemoteContextForNotifications";
     public static final String ALLOW_STARTING_SERVICE_MANAGER_ONLY =
@@ -237,8 +238,8 @@
     public static final String INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE =
             "IntentBlockExternalFormRedirectsNoGesture";
     public static final String INTEREST_FEED_CONTENT_SUGGESTIONS = "InterestFeedContentSuggestions";
-    public static final String LANGUAGES_PREFERENCE = "LanguagesPreference";
     public static final String JELLY_BEAN_SUPPORTED = "JellyBeanSupported";
+    public static final String LANGUAGES_PREFERENCE = "LanguagesPreference";
     public static final String SEARCH_ENGINE_PROMO_EXISTING_DEVICE =
             "SearchEnginePromo.ExistingDevice";
     public static final String SEARCH_ENGINE_PROMO_NEW_DEVICE = "SearchEnginePromo.NewDevice";
@@ -281,6 +282,7 @@
             "PredictivePrefetchingAllowedOnAllConnectionTypes";
     public static final String PROGRESS_BAR_THROTTLE = "ProgressBarThrottle";
     public static final String PWA_PERSISTENT_NOTIFICATION = "PwaPersistentNotification";
+    public static final String REACHED_CODE_PROFILER = "ReachedCodeProfiler";
     public static final String READER_MODE_IN_CCT = "ReaderModeInCCT";
     public static final String REMOVE_NAVIGATION_HISTORY = "RemoveNavigationHistory";
     public static final String SEARCH_READY_OMNIBOX = "SearchReadyOmnibox";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 14368f2..f549a57 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -87,6 +87,7 @@
 import org.chromium.chrome.browser.incognito.IncognitoNotificationManager;
 import org.chromium.chrome.browser.incognito.IncognitoTabHost;
 import org.chromium.chrome.browser.incognito.IncognitoTabHostRegistry;
+import org.chromium.chrome.browser.incognito.IncognitoTabLauncher;
 import org.chromium.chrome.browser.incognito.IncognitoTabSnapshotController;
 import org.chromium.chrome.browser.incognito.IncognitoUtils;
 import org.chromium.chrome.browser.infobar.DataReductionPromoInfoBar;
@@ -1319,16 +1320,19 @@
 
                     if (url == null || url.equals(UrlConstants.NTP_URL)) {
                         if (fromLauncherShortcut) {
-                            getTabCreator(true).launchUrl(
-                                    UrlConstants.NTP_URL, TabLaunchType.FROM_LAUNCHER_SHORTCUT);
+                            getTabCreator(true).launchUrl(UrlConstants.NTP_URL,
+                                    TabLaunchType.FROM_LAUNCHER_SHORTCUT);
                             recordLauncherShortcutAction(true);
                             reportNewTabShortcutUsed(true);
+                        } else if (IncognitoTabLauncher.didCreateIntent(intent)) {
+                            getTabCreator(true).launchUrl(UrlConstants.NTP_URL,
+                                    TabLaunchType.FROM_LAUNCH_NEW_INCOGNITO_TAB);
+                            IncognitoTabLauncher.recordUse();
                         } else {
                             // Used by the Account management screen to open a new incognito tab.
                             // Account management screen collects its metrics separately.
-                            getTabCreator(true).launchUrl(
-                                    UrlConstants.NTP_URL, TabLaunchType.FROM_CHROME_UI,
-                                    intent, mIntentHandlingTimeMs);
+                            getTabCreator(true).launchUrl(UrlConstants.NTP_URL,
+                                    TabLaunchType.FROM_CHROME_UI, intent, mIntentHandlingTimeMs);
                         }
                     } else {
                         @TabLaunchType
@@ -1983,16 +1987,20 @@
             // the back button to close these tabs and restore selection to the previous tab.
             boolean isIncognito = IntentUtils.safeGetBooleanExtra(intent,
                     IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false);
-            boolean fromLauncherShortcut = IntentUtils.safeGetBooleanExtra(
-                    intent, IntentHandler.EXTRA_INVOKED_FROM_SHORTCUT, false);
             LoadUrlParams loadUrlParams = new LoadUrlParams(url);
             loadUrlParams.setIntentReceivedTimestamp(mIntentHandlingTimeMs);
             loadUrlParams.setVerbatimHeaders(headers);
             @TabLaunchType
             Integer launchType = IntentHandler.getTabLaunchType(intent);
             if (launchType == null) {
-                launchType = fromLauncherShortcut ? TabLaunchType.FROM_LAUNCHER_SHORTCUT
-                                                  : TabLaunchType.FROM_LINK;
+                if (IntentUtils.safeGetBooleanExtra(intent,
+                        IntentHandler.EXTRA_INVOKED_FROM_SHORTCUT, false)) {
+                    launchType = TabLaunchType.FROM_LAUNCHER_SHORTCUT;
+                } else if (IncognitoTabLauncher.didCreateIntent(intent)) {
+                    launchType = TabLaunchType.FROM_LAUNCH_NEW_INCOGNITO_TAB;
+                } else {
+                    launchType = TabLaunchType.FROM_LINK;
+                }
             }
             return getTabCreator(isIncognito).createNewTab(loadUrlParams, launchType, null, intent);
         } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
index 933622e3..038ca65 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
@@ -141,6 +141,13 @@
             "com.android.chrome.invoked_from_shortcut";
 
     /**
+     * An extra to indicate that the intent was triggered by the launch new incognito tab feature.
+     * See {@link org.chromium.chrome.browser.incognito.IncognitoTabLauncher}.
+     */
+    public static final String EXTRA_INVOKED_FROM_LAUNCH_NEW_INCOGNITO_TAB =
+            "org.chromium.chrome.browser.incognito.invoked_from_launch_new_incognito_tab";
+
+    /**
      * Intent extra used to identify the sending application.
      */
     private static final String TRUSTED_APPLICATION_CODE_EXTRA = "trusted_application_code_extra";
@@ -1323,4 +1330,24 @@
     public static @Nullable @TabLaunchType Integer getTabLaunchType(Intent intent) {
         return IntentUtils.safeGetSerializableExtra(intent, EXTRA_TAB_LAUNCH_TYPE);
     }
+
+    /**
+     * Creates an Intent that will launch a ChromeTabbedActivity on the new tab page. The Intent
+     * will be trusted and therefore able to launch Incognito tabs.
+     * @param context A {@link Context} to access class and package information.
+     * @param incognito Whether the tab should be opened in Incognito.
+     * @return The {@link Intent} to launch.
+     */
+    public static Intent createTrustedOpenNewTabIntent(Context context, boolean incognito) {
+        Intent newIntent = new Intent();
+        newIntent.setAction(Intent.ACTION_VIEW);
+        newIntent.setData(Uri.parse(UrlConstants.NTP_URL));
+        newIntent.setClass(context, ChromeLauncherActivity.class);
+        newIntent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
+        newIntent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
+        newIntent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, incognito);
+        IntentHandler.addTrustedIntentExtras(newIntent);
+
+        return newIntent;
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LauncherShortcutActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/LauncherShortcutActivity.java
index d134616..5c4a5a02 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/LauncherShortcutActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/LauncherShortcutActivity.java
@@ -12,16 +12,13 @@
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
 import android.graphics.drawable.Icon;
-import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.StrictMode;
-import android.provider.Browser;
 import android.support.annotation.VisibleForTesting;
 
 import org.chromium.base.ContextUtils;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 
 import java.util.ArrayList;
@@ -142,18 +139,9 @@
     @VisibleForTesting
     public static Intent getChromeLauncherActivityIntent(
             Context context, String launcherShortcutIntentAction) {
-        Intent newIntent = new Intent();
-        newIntent.setAction(Intent.ACTION_VIEW);
-        newIntent.setData(Uri.parse(UrlConstants.NTP_URL));
-        newIntent.setClass(context, ChromeLauncherActivity.class);
+        Intent newIntent = IntentHandler.createTrustedOpenNewTabIntent(context,
+                launcherShortcutIntentAction.equals(ACTION_OPEN_NEW_INCOGNITO_TAB));
         newIntent.putExtra(IntentHandler.EXTRA_INVOKED_FROM_SHORTCUT, true);
-        newIntent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
-        newIntent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
-        IntentHandler.addTrustedIntentExtras(newIntent);
-
-        if (launcherShortcutIntentAction.equals(ACTION_OPEN_NEW_INCOGNITO_TAB)) {
-            newIntent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
-        }
 
         return newIntent;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java
index 1d5ce485..01d26a3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java
@@ -63,6 +63,7 @@
         final ImageView mImageView;
         final TextView mTitleView;
         final TextView mSubtextView;
+        final TextView mTotalPriceView;
 
         public ViewHolder(Context context, View detailsView) {
             mDefaultImage = (GradientDrawable) context.getResources().getDrawable(
@@ -70,6 +71,7 @@
             mImageView = detailsView.findViewById(R.id.details_image);
             mTitleView = detailsView.findViewById(R.id.details_title);
             mSubtextView = detailsView.findViewById(R.id.details_text);
+            mTotalPriceView = detailsView.findViewById(R.id.total_price);
         }
     }
 
@@ -112,6 +114,7 @@
         String detailsText = makeDetailsText(details);
         viewHolder.mTitleView.setText(details.getTitle());
         viewHolder.mSubtextView.setText(detailsText);
+        viewHolder.mTotalPriceView.setText(details.getPrice());
 
         if (viewHolder.mImageView.getDrawable() == null) {
             // Set default image if no image was set before.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncher.java
new file mode 100644
index 0000000..aaafb8e
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncher.java
@@ -0,0 +1,115 @@
+// 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.incognito;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+
+import org.chromium.base.StrictModeContext;
+import org.chromium.base.VisibleForTesting;
+import org.chromium.base.metrics.RecordUserAction;
+import org.chromium.base.task.AsyncTask;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.ChromeVersionInfo;
+import org.chromium.chrome.browser.IntentHandler;
+import org.chromium.chrome.browser.preferences.PrefServiceBridge;
+import org.chromium.chrome.browser.util.IntentUtils;
+
+/**
+ * An exposed Activity that allows launching an Incognito Tab.
+ *
+ * No URL or search term can be entered in, the Incognito tab is started with a blank (but focused)
+ * omnibox. This component will be disabled if incognito mode is disabled.
+ * TODO(peconn): Focus the omnibox when the Incognito tab is opened.
+ */
+public class IncognitoTabLauncher extends Activity {
+    /** The Intent action used to launch the IncognitoTabLauncher. */
+    @VisibleForTesting
+    public static final String ACTION_LAUNCH_NEW_INCOGNITO_TAB =
+            "org.chromium.chrome.browser.incognito.OPEN_PRIVATE_TAB";
+
+    /**
+     * An Action that will disable this component on local builds only, to help development and
+     * debugging.
+     */
+    private static final String ACTION_DEBUG =
+            "org.chromium.chrome.browser.incognito.IncognitoTabLauncher.DISABLE";
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (ChromeVersionInfo.isLocalBuild() && ACTION_DEBUG.equals(getIntent().getAction())) {
+            setComponentEnabled(this, false);
+            finish();
+            return;
+        }
+
+        Intent chromeLauncherIntent = IntentHandler.createTrustedOpenNewTabIntent(this, true);
+        chromeLauncherIntent.putExtra(
+                IntentHandler.EXTRA_INVOKED_FROM_LAUNCH_NEW_INCOGNITO_TAB, true);
+
+        try (StrictModeContext unused = StrictModeContext.allowDiskWrites()) {
+            startActivity(chromeLauncherIntent);
+        }
+
+        finish();
+    }
+
+    /**
+     * Returns whether the intent was created by this Activity as part of the Launch New Incognito
+     * Tab flow.
+     */
+    public static boolean didCreateIntent(Intent intent) {
+        return IntentHandler.wasIntentSenderChrome(intent) && IntentUtils.safeGetBooleanExtra(
+                intent, IntentHandler.EXTRA_INVOKED_FROM_LAUNCH_NEW_INCOGNITO_TAB, false);
+    }
+
+    /**
+     * Records UMA that a new incognito tab has been launched as a result of this Activity.
+     */
+    public static void recordUse() {
+        RecordUserAction.record("Android.LaunchNewIncognitoTab");
+    }
+
+    /**
+     * Checks whether Incognito mode is enabled for the user and enables/disables the
+     * IncognitoLauncherActivity appropriately. This call requires native to be loaded.
+     */
+    public static void updateComponentEnabledState(Context context) {
+        // TODO(peconn): Update state in a few more places (eg CustomTabsConnection#warmup).
+        boolean enable = ChromeFeatureList.isEnabled(
+                        ChromeFeatureList.ALLOW_NEW_INCOGNITO_TAB_INTENTS)
+                && PrefServiceBridge.getInstance().isIncognitoModeEnabled();
+
+        AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> setComponentEnabled(context, enable));
+    }
+
+    /**
+     * Sets whether or not the IncognitoTabLauncher should be enabled. This may trigger a StrictMode
+     * violation so shouldn't be called on the UI thread.
+     */
+    @VisibleForTesting
+    static void setComponentEnabled(Context context, boolean enabled) {
+        PackageManager packageManager = context.getPackageManager();
+        ComponentName componentName = new ComponentName(context, IncognitoTabLauncher.class);
+
+        int newState = enabled
+                ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+                : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+
+        // This indicates that we don't want to kill Chrome when changing component enabled state.
+        int flags = PackageManager.DONT_KILL_APP;
+
+        if (packageManager.getComponentEnabledSetting(componentName) != newState) {
+            packageManager.setComponentEnabledSetting(componentName, newState, flags);
+        }
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
index 0eca769..45269c4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -242,6 +242,9 @@
         ChromeStrictMode.configureStrictMode();
         ChromeWebApkHost.init();
 
+        // Time this call takes in background from test devices:
+        // - Pixel 2: ~10 ms
+        // - Nokia 1 (Android Go): 20-200 ms
         warmUpSharedPrefs();
 
         DeviceUtils.addDeviceSpecificUserAgentSwitch();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
index 29938e1..1be98cca 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
@@ -47,6 +47,7 @@
 import org.chromium.chrome.browser.firstrun.ForcedSigninProcessor;
 import org.chromium.chrome.browser.identity.UniqueIdentificationGeneratorFactory;
 import org.chromium.chrome.browser.identity.UuidBasedUniqueIdentificationGenerator;
+import org.chromium.chrome.browser.incognito.IncognitoTabLauncher;
 import org.chromium.chrome.browser.invalidation.UniqueIdInvalidationClientNameGenerator;
 import org.chromium.chrome.browser.locale.LocaleManager;
 import org.chromium.chrome.browser.media.MediaCaptureNotificationService;
@@ -408,31 +409,24 @@
             }
         });
 
-        deferredStartupHandler.addDeferredTask(new Runnable() {
-            @Override
-            public void run() {
-                BackgroundTaskSchedulerFactory.getScheduler().checkForOSUpgrade(application);
-            }
-        });
-
-        deferredStartupHandler.addDeferredTask(new Runnable() {
-            @Override
-            public void run() {
-                logEGLShaderCacheSizeHistogram();
-            }
-        });
+        deferredStartupHandler.addDeferredTask(
+                () -> BackgroundTaskSchedulerFactory.getScheduler().checkForOSUpgrade(application));
 
         deferredStartupHandler.addDeferredTask(
-                () -> { BuildHooksAndroid.maybeRecordResourceMetrics(); });
+                ProcessInitializationHandler::logEGLShaderCacheSizeHistogram);
 
-        deferredStartupHandler.addDeferredTask(() -> {
-            MediaViewerUtils.updateMediaLauncherActivityEnabled(
-                    ContextUtils.getApplicationContext());
-        });
+        deferredStartupHandler.addDeferredTask(
+                BuildHooksAndroid::maybeRecordResourceMetrics);
+
+        deferredStartupHandler.addDeferredTask(
+                () -> MediaViewerUtils.updateMediaLauncherActivityEnabled(application));
 
         deferredStartupHandler.addDeferredTask(
                 ChromeApplication.getComponent().resolveTwaClearDataDialogRecorder()
                         ::makeDeferredRecordings);
+
+        deferredStartupHandler.addDeferredTask(
+                () ->  IncognitoTabLauncher.updateComponentEnabledState(application));
     }
 
     private void initChannelsAsync() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
index eeeecf8..cabe5fc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
@@ -300,6 +300,7 @@
                 break;
             case TabLaunchType.FROM_CHROME_UI:
             case TabLaunchType.FROM_LAUNCHER_SHORTCUT:
+            case TabLaunchType.FROM_LAUNCH_NEW_INCOGNITO_TAB:
                 transition = PageTransition.AUTO_TOPLEVEL;
                 break;
             case TabLaunchType.FROM_LONGPRESS_FOREGROUND:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java
index c98b154..01e7c367a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java
@@ -77,7 +77,8 @@
                 manuallyCreatedCount++;
             } else if (tabLaunchType == TabLaunchType.FROM_LONGPRESS_FOREGROUND) {
                 targetBlankCreatedCount++;
-            } else if (tabLaunchType == TabLaunchType.FROM_EXTERNAL_APP) {
+            } else if (tabLaunchType == TabLaunchType.FROM_EXTERNAL_APP
+                    || tabLaunchType == TabLaunchType.FROM_LAUNCH_NEW_INCOGNITO_TAB) {
                 externalAppCreatedCount++;
             } else {
                 othersCreatedCount++;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
index b3137f8..441c875 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -195,11 +195,13 @@
         cacheNightModeAvailable();
         cacheDownloadAutoResumptionEnabledInNative();
 
-        // Propagate DONT_PREFETCH_LIBRARIES feature value to LibraryLoader. This can't
-        // be done in LibraryLoader itself because it lives in //base and can't depend
-        // on ChromeFeatureList.
+        // Propagate DONT_PREFETCH_LIBRARIES and REACHED_CODE_PROFILER feature values to
+        // LibraryLoader. This can't be done in LibraryLoader itself because it lives in //base and
+        // can't depend on ChromeFeatureList.
         LibraryLoader.setDontPrefetchLibrariesOnNextRuns(
                 ChromeFeatureList.isEnabled(ChromeFeatureList.DONT_PREFETCH_LIBRARIES));
+        LibraryLoader.setReachedCodeProfilerEnabledOnNextRuns(
+                ChromeFeatureList.isEnabled(ChromeFeatureList.REACHED_CODE_PROFILER));
     }
 
     /**
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 306f8d5..489b1df4b 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -793,6 +793,7 @@
   "java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java",
   "java/src/org/chromium/chrome/browser/incognito/IncognitoTabHost.java",
   "java/src/org/chromium/chrome/browser/incognito/IncognitoTabHostRegistry.java",
+  "java/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncher.java",
   "java/src/org/chromium/chrome/browser/incognito/IncognitoTabSnapshotController.java",
   "java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java",
   "java/src/org/chromium/chrome/browser/infobar/AdsBlockedInfoBar.java",
@@ -1903,6 +1904,7 @@
   "javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java",
   "javatests/src/org/chromium/chrome/browser/PrerenderTest.java",
   "javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java",
+  "javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java",
   "javatests/src/org/chromium/chrome/browser/RestoreHistogramTest.java",
   "javatests/src/org/chromium/chrome/browser/SafeBrowsingTest.java",
   "javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java",
@@ -2062,6 +2064,7 @@
   "javatests/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGeneratorTest.java",
   "javatests/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureDialogAppearanceTest.java",
   "javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java",
+  "javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java",
   "javatests/src/org/chromium/chrome/browser/infobar/InfoBarAppearanceTest.java",
   "javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java",
   "javatests/src/org/chromium/chrome/browser/infobar/InfoBarControlLayoutTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerTest.java
index 0fdd910..4b0f7c79 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerTest.java
@@ -463,4 +463,23 @@
         checkIntentForMhtmlFileOrContent(INTENT_URLS_AND_TYPES_FOR_MHTML, true);
         checkIntentForMhtmlFileOrContent(INTENT_URLS_AND_TYPES_NOT_FOR_MHTML, false);
     }
+
+    @Test
+    @SmallTest
+    @Feature({"Android-AppBase"})
+    public void testCreateTrustedOpenNewTabIntent() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        Intent intent = IntentHandler.createTrustedOpenNewTabIntent(context, true);
+
+        Assert.assertEquals(intent.getAction(), Intent.ACTION_VIEW);
+        Assert.assertEquals(intent.getData(), Uri.parse(UrlConstants.NTP_URL));
+        Assert.assertTrue(intent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false));
+        Assert.assertTrue(IntentHandler.wasIntentSenderChrome(intent));
+        Assert.assertTrue(
+                intent.getBooleanExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false));
+
+        intent = IntentHandler.createTrustedOpenNewTabIntent(context, false);
+        Assert.assertFalse(
+                intent.getBooleanExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true));
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java
new file mode 100644
index 0000000..fa025940
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java
@@ -0,0 +1,118 @@
+// 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;
+
+import android.support.test.filters.SmallTest;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.BaseSwitches;
+import org.chromium.base.StrictModeContext;
+import org.chromium.base.test.ReachedCodeProfiler;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
+import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
+
+/**
+ * Tests for the reached code profiler feature setup.
+ */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+public final class ReachedCodeProfilerTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
+    // Shared preferences key for the reached code profiler.
+    private static final String REACHED_CODE_PROFILER_ENABLED_KEY = "reached_code_profiler_enabled";
+
+    /**
+     * Tests that passing a command line switch enables the reached code profiler no matter what.
+     */
+    @Test
+    @SmallTest
+    @DisableFeatures(ChromeFeatureList.REACHED_CODE_PROFILER)
+    @CommandLineFlags.Add(BaseSwitches.ENABLE_REACHED_CODE_PROFILER)
+    public void testExplicitlyEnableViaCommandLineSwitch() throws Exception {
+        mActivityTestRule.startMainActivityFromLauncher();
+        assertReachedCodeProfilerIsEnabled();
+    }
+
+    /**
+     * Tests that setting a shared preference enables the reached code profiler. This test imitates
+     * the second launch after enabling the feature
+     */
+    @Test
+    @SmallTest
+    @EnableFeatures(ChromeFeatureList.REACHED_CODE_PROFILER)
+    public void testEnabledViaCachedSharedPreference() throws Exception {
+        setReachedCodeProfilerSharedPreference(true);
+        mActivityTestRule.startMainActivityFromLauncher();
+        assertReachedCodeProfilerIsEnabled();
+    }
+
+    /**
+     * Tests that the feature state is cached in shared preferences after native initialization.
+     * This test imitates the first run when the feature is enabled.
+     */
+    @Test
+    @SmallTest
+    @EnableFeatures(ChromeFeatureList.REACHED_CODE_PROFILER)
+    public void testSharedPreferenceIsCached_Enable() throws Exception {
+        mActivityTestRule.startMainActivityFromLauncher();
+
+        Assert.assertTrue(getReachedCodeProfilerSharedPreference());
+        // Enabling takes effect only on the second startup.
+        Assert.assertFalse(ReachedCodeProfiler.isEnabled());
+    }
+
+    /**
+     * Tests that the feature state is cached in shared preferences after native initialization.
+     * This test imitates disabling the reached code profiler after it has been enabled for some
+     * time.
+     */
+    @Test
+    @SmallTest
+    @DisableFeatures(ChromeFeatureList.REACHED_CODE_PROFILER)
+    public void testSharedPreferenceIsCached_Disable() throws Exception {
+        setReachedCodeProfilerSharedPreference(true);
+        mActivityTestRule.startMainActivityFromLauncher();
+
+        Assert.assertFalse(getReachedCodeProfilerSharedPreference());
+        // Disabling takes effect only on the second startup.
+        assertReachedCodeProfilerIsEnabled();
+    }
+
+    /**
+     * The reached code profiler is always disabled in some configurations. This helper allows to
+     * check if the profiler is enabled in supported configurations.
+     */
+    private void assertReachedCodeProfilerIsEnabled() {
+        if (!ReachedCodeProfiler.isSupported()) {
+            Assert.assertFalse(ReachedCodeProfiler.isEnabled());
+            return;
+        }
+
+        Assert.assertTrue(ReachedCodeProfiler.isEnabled());
+    }
+
+    private boolean getReachedCodeProfilerSharedPreference() {
+        try (StrictModeContext unused = StrictModeContext.allowDiskReads()) {
+            return ChromePreferenceManager.getInstance().readBoolean(
+                    REACHED_CODE_PROFILER_ENABLED_KEY, false);
+        }
+    }
+
+    private void setReachedCodeProfilerSharedPreference(boolean value) {
+        ChromePreferenceManager.getInstance().writeBoolean(
+                REACHED_CODE_PROFILER_ENABLED_KEY, value);
+    }
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java
new file mode 100644
index 0000000..bdc43bda
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java
@@ -0,0 +1,82 @@
+// 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.incognito;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.browser.Features;
+
+/**
+ * Tests for {@link IncognitoTabLauncher}.
+ */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+@Features.EnableFeatures({ChromeFeatureList.ALLOW_NEW_INCOGNITO_TAB_INTENTS})
+public class IncognitoTabLauncherTest {
+    @Test
+    @Feature("Incognito")
+    @SmallTest
+    public void testEnableComponent() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        IncognitoTabLauncher.setComponentEnabled(context, true);
+        Assert.assertNotNull(
+                context.getPackageManager().resolveActivity(createLaunchIntent(context), 0));
+    }
+
+    @Test
+    @Feature("Incognito")
+    @SmallTest
+    public void testDisableComponent() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        IncognitoTabLauncher.setComponentEnabled(context, false);
+        Assert.assertNull(
+                context.getPackageManager().resolveActivity(createLaunchIntent(context), 0));
+    }
+
+    @Test
+    @Feature("Incognito")
+    @MediumTest
+    public void testLaunchIncognitoNewTab() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        IncognitoTabLauncher.setComponentEnabled(context, true);
+        Intent intent = createLaunchIntent(context);
+
+        // We need FLAG_ACTIVITY_NEW_TASK because we're calling from the application context (not an
+        // Activity context). This is fine though because ChromeActivityTestRule.waitFor uses
+        // ApplicationStatus internally, which ignores Tasks and tracks all Chrome Activities.
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        ThreadUtils.runOnUiThreadBlocking(() -> context.startActivity(intent));
+
+        ChromeTabbedActivity activity = ChromeActivityTestRule.waitFor(ChromeTabbedActivity.class);
+        Assert.assertTrue(activity.getTabModelSelector().isIncognitoSelected());
+        Assert.assertTrue(IncognitoTabLauncher.didCreateIntent(activity.getIntent()));
+    }
+
+    private Intent createLaunchIntent(Context context) {
+        Intent intent = new Intent(IncognitoTabLauncher.ACTION_LAUNCH_NEW_INCOGNITO_TAB);
+        // Restrict ourselves to Chrome's package, on the off chance the testing device has another
+        // application that answers to the ACTION_LAUNCH_NEW_INCOGNITO_TAB action.
+        intent.setPackage(context.getPackageName());
+
+        return intent;
+    }
+}
\ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
index 022c093..c5962faed 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
@@ -710,7 +710,12 @@
                     testServer.getURL("/chrome/test/data/android/theme_color_test.html");
 
             mActivityTestRule.loadUrl(testHttpsUrl);
-            didThemeColorChangedCallbackHelper.waitForCallback(0);
+
+            // Tablets don't have website theme colors.
+            if (!mActivityTestRule.getActivity().isTablet()) {
+                didThemeColorChangedCallbackHelper.waitForCallback(0);
+            }
+
             onSSLStateUpdatedCallbackHelper.waitForCallback(0);
 
             LocationBarLayout locationBarLayout =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java
index 50ca2765..72e198f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java
@@ -17,6 +17,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
@@ -167,6 +168,7 @@
     @Test
     @LargeTest
     @Feature({"Sync"})
+    @DisabledTest // https://crbug.com/930729
     public void testDownloadMovedBookmark() throws Exception {
         // Add the entity to test moving.
         addServerBookmark(TITLE, URL);
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index b37b27d..9a5ca4b 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-74.0.3702.0_rc-r1.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-74.0.3703.0_rc-r1-merged.afdo.bz2
\ No newline at end of file
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 09eaf12..96f1b19 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -86,6 +86,7 @@
     &feed::kInterestFeedContentSuggestions,
     &invalidation::switches::kFCMInvalidations,
     &kAdjustWebApkInstallationSpace,
+    &kAllowNewIncognitoTabIntents,
     &kAllowRemoteContextForNotifications,
     &kAndroidNightMode,
     &kAndroidPayIntegrationV1,
@@ -145,6 +146,7 @@
     &kProgressBarThrottleFeature,
     &kPwaImprovedSplashScreen,
     &kPwaPersistentNotification,
+    &kReachedCodeProfiler,
     &kReaderModeInCCT,
     &kSearchReadyOmniboxFeature,
     &kSearchEnginePromoExistingDevice,
@@ -217,6 +219,9 @@
 const base::Feature kAndroidPayIntegrationV1{"AndroidPayIntegrationV1",
                                              base::FEATURE_ENABLED_BY_DEFAULT};
 
+const base::Feature kAllowNewIncognitoTabIntents{
+    "AllowNewIncognitoTabIntents", base::FEATURE_ENABLED_BY_DEFAULT};
+
 const base::Feature kAllowRemoteContextForNotifications{
     "AllowRemoteContextForNotifications", base::FEATURE_ENABLED_BY_DEFAULT};
 
@@ -408,6 +413,9 @@
 const base::Feature kPwaPersistentNotification{
     "PwaPersistentNotification", base::FEATURE_ENABLED_BY_DEFAULT};
 
+const base::Feature kReachedCodeProfiler{"ReachedCodeProfiler",
+                                         base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kReaderModeInCCT{"ReaderModeInCCT",
                                      base::FEATURE_ENABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h
index e19b0130..ae57167 100644
--- a/chrome/browser/android/chrome_feature_list.h
+++ b/chrome/browser/android/chrome_feature_list.h
@@ -13,6 +13,7 @@
 
 // Alphabetical:
 extern const base::Feature kAdjustWebApkInstallationSpace;
+extern const base::Feature kAllowNewIncognitoTabIntents;
 extern const base::Feature kAllowRemoteContextForNotifications;
 extern const base::Feature kAndroidNightMode;
 extern const base::Feature kAndroidPayIntegrationV1;
@@ -77,6 +78,7 @@
 extern const base::Feature kProgressBarThrottleFeature;
 extern const base::Feature kPwaImprovedSplashScreen;
 extern const base::Feature kPwaPersistentNotification;
+extern const base::Feature kReachedCodeProfiler;
 extern const base::Feature kReaderModeInCCT;
 extern const base::Feature kSearchReadyOmniboxFeature;
 extern const base::Feature kServiceManagerForDownload;
diff --git a/chrome/browser/autofill/personal_data_manager_factory.cc b/chrome/browser/autofill/personal_data_manager_factory.cc
index f1a36646..1199b94 100644
--- a/chrome/browser/autofill/personal_data_manager_factory.cc
+++ b/chrome/browser/autofill/personal_data_manager_factory.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
@@ -38,7 +37,6 @@
   DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(WebDataServiceFactory::GetInstance());
-  DependsOn(GaiaCookieManagerServiceFactory::GetInstance());
 }
 
 PersonalDataManagerFactory::~PersonalDataManagerFactory() {
@@ -59,7 +57,6 @@
   service->Init(local_storage, account_storage, profile->GetPrefs(),
                 IdentityManagerFactory::GetForProfile(profile),
                 autofill_validator, history_service,
-                GaiaCookieManagerServiceFactory::GetForProfile(profile),
                 profile->IsOffTheRecord());
   return service;
 }
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_win.cc b/chrome/browser/browser_switcher/browser_switcher_service_win.cc
index 1bc3b0d..c60a611 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service_win.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_service_win.cc
@@ -98,6 +98,13 @@
   UMA_HISTOGRAM_BOOLEAN("BrowserSwitcher.CacheFile.MoveSuccess", success);
 }
 
+// URL to fetch the IEEM sitelist from. Only used for testing.
+base::Optional<std::string>* IeemSitelistUrlForTesting() {
+  static base::NoDestructor<base::Optional<std::string>>
+      ieem_sitelist_url_for_testing;
+  return ieem_sitelist_url_for_testing.get();
+}
+
 }  // namespace
 
 BrowserSwitcherServiceWin::BrowserSwitcherServiceWin(Profile* profile)
@@ -127,19 +134,16 @@
 
 BrowserSwitcherServiceWin::~BrowserSwitcherServiceWin() = default;
 
-base::Optional<std::string>
-    BrowserSwitcherServiceWin::ieem_sitelist_url_for_testing_;
-
 // static
 void BrowserSwitcherServiceWin::SetIeemSitelistUrlForTesting(
     const std::string& spec) {
-  ieem_sitelist_url_for_testing_ = spec;
+  *IeemSitelistUrlForTesting() = spec;
 }
 
 // static
 GURL BrowserSwitcherServiceWin::GetIeemSitelistUrl() {
-  if (ieem_sitelist_url_for_testing_ != base::nullopt)
-    return GURL(*ieem_sitelist_url_for_testing_);
+  if (*IeemSitelistUrlForTesting() != base::nullopt)
+    return GURL((*IeemSitelistUrlForTesting()).value());
 
   base::win::RegKey key;
   if (ERROR_SUCCESS != key.Open(HKEY_LOCAL_MACHINE, kIeSiteListKey, KEY_READ) &&
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_win.h b/chrome/browser/browser_switcher/browser_switcher_service_win.h
index 851398b..ff44535 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service_win.h
+++ b/chrome/browser/browser_switcher/browser_switcher_service_win.h
@@ -31,9 +31,6 @@
 
   std::unique_ptr<XmlDownloader> ieem_downloader_;
 
-  // URL to fetch the IEEM sitelist from. Only used for testing.
-  static base::Optional<std::string> ieem_sitelist_url_for_testing_;
-
   base::WeakPtrFactory<BrowserSwitcherServiceWin> weak_ptr_factory_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(BrowserSwitcherServiceWin);
diff --git a/chrome/browser/chromeos/accessibility/switch_access_panel.cc b/chrome/browser/chromeos/accessibility/switch_access_panel.cc
index ab7d0be..42711084 100644
--- a/chrome/browser/chromeos/accessibility/switch_access_panel.cc
+++ b/chrome/browser/chromeos/accessibility/switch_access_panel.cc
@@ -6,6 +6,7 @@
 
 #include "ash/public/interfaces/accessibility_controller.mojom.h"
 #include "ash/public/interfaces/constants.mojom.h"
+#include "base/no_destructor.h"
 #include "content/public/common/service_manager_connection.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "ui/display/display.h"
@@ -17,15 +18,17 @@
 const char kWidgetName[] = "SwitchAccessMenu";
 const int kFocusRingBuffer = 5;
 
+const std::string& UrlForContent() {
+  static const base::NoDestructor<std::string> url(
+      std::string(EXTENSION_PREFIX) + extension_misc::kSwitchAccessExtensionId +
+      "/menu_panel.html");
+  return *url;
+}
+
 }  // namespace
 
-// static
-const std::string urlForContent = std::string(EXTENSION_PREFIX) +
-                                  extension_misc::kSwitchAccessExtensionId +
-                                  "/menu_panel.html";
-
 SwitchAccessPanel::SwitchAccessPanel(content::BrowserContext* browser_context)
-    : AccessibilityPanel(browser_context, urlForContent, kWidgetName) {
+    : AccessibilityPanel(browser_context, UrlForContent(), kWidgetName) {
   Hide();
 }
 
diff --git a/chrome/browser/chromeos/arc/process/arc_process.cc b/chrome/browser/chromeos/arc/process/arc_process.cc
index 17088eb..3b917c5 100644
--- a/chrome/browser/chromeos/arc/process/arc_process.cc
+++ b/chrome/browser/chromeos/arc/process/arc_process.cc
@@ -7,6 +7,7 @@
 #include <unordered_set>
 #include <utility>
 
+#include "base/no_destructor.h"
 #include "base/strings/string_util.h"
 
 namespace arc {
@@ -16,42 +17,51 @@
 constexpr char kCloudDpcrocessName[] =
     "com.google.android.apps.work.clouddpc.arc";
 
-const std::unordered_set<ProcessState> kImportantStates = {
-    ProcessState::IMPORTANT_FOREGROUND,
-    ProcessState::BOUND_FOREGROUND_SERVICE,
-    ProcessState::FOREGROUND_SERVICE,
-    ProcessState::TOP,
-    ProcessState::PERSISTENT_UI,
-    ProcessState::PERSISTENT
-};
-const std::unordered_set<ProcessState> kPersistentStates = {
-    ProcessState::PERSISTENT_UI,
-    ProcessState::PERSISTENT
-};
-const std::unordered_set<ProcessState> kProtectedBackgroundStates = {
-    ProcessState::TOP,
-    ProcessState::FOREGROUND_SERVICE,
-    ProcessState::BOUND_FOREGROUND_SERVICE,
-    ProcessState::IMPORTANT_FOREGROUND,
-    ProcessState::IMPORTANT_FOREGROUND
-};
-const std::unordered_set<ProcessState> kBackgroundStates = {
-    ProcessState::TRANSIENT_BACKGROUND,
-    ProcessState::BACKUP,
-    ProcessState::SERVICE,
-    ProcessState::RECEIVER,
-    ProcessState::TOP_SLEEPING,
-    ProcessState::HEAVY_WEIGHT,
-    ProcessState::HOME,
-    ProcessState::LAST_ACTIVITY,
-    ProcessState::CACHED_ACTIVITY
-};
-const std::unordered_set<ProcessState> kCachedStates = {
-    ProcessState::CACHED_ACTIVITY_CLIENT,
-    ProcessState::CACHED_RECENT,
-    ProcessState::CACHED_EMPTY,
-    ProcessState::NONEXISTENT
-};
+const std::unordered_set<ProcessState>& ImportantStates() {
+  static const base::NoDestructor<std::unordered_set<ProcessState>>
+      kImportantStates({ProcessState::IMPORTANT_FOREGROUND,
+                        ProcessState::BOUND_FOREGROUND_SERVICE,
+                        ProcessState::FOREGROUND_SERVICE, ProcessState::TOP,
+                        ProcessState::PERSISTENT_UI, ProcessState::PERSISTENT});
+  return *kImportantStates;
+}
+
+const std::unordered_set<ProcessState>& PersistentStates() {
+  static const base::NoDestructor<std::unordered_set<ProcessState>>
+      kPersistentStates(
+          {ProcessState::PERSISTENT_UI, ProcessState::PERSISTENT});
+  return *kPersistentStates;
+}
+
+
+const std::unordered_set<ProcessState>& ProtectedBackgroundStates() {
+  static const base::NoDestructor<std::unordered_set<ProcessState>>
+      kProtectedBackgroundStates({ProcessState::TOP,
+                                  ProcessState::FOREGROUND_SERVICE,
+                                  ProcessState::BOUND_FOREGROUND_SERVICE,
+                                  ProcessState::IMPORTANT_FOREGROUND,
+                                  ProcessState::IMPORTANT_FOREGROUND});
+  return *kProtectedBackgroundStates;
+}
+
+const std::unordered_set<ProcessState>& BackgroundStates() {
+  static const base::NoDestructor<std::unordered_set<ProcessState>>
+      kBackgroundStates({ProcessState::TRANSIENT_BACKGROUND,
+                         ProcessState::BACKUP, ProcessState::SERVICE,
+                         ProcessState::RECEIVER, ProcessState::TOP_SLEEPING,
+                         ProcessState::HEAVY_WEIGHT, ProcessState::HOME,
+                         ProcessState::LAST_ACTIVITY,
+                         ProcessState::CACHED_ACTIVITY});
+  return *kBackgroundStates;
+}
+
+const std::unordered_set<ProcessState>& CachedStates() {
+  static const base::NoDestructor<std::unordered_set<ProcessState>>
+      kCachedStates({ProcessState::CACHED_ACTIVITY_CLIENT,
+                     ProcessState::CACHED_RECENT, ProcessState::CACHED_EMPTY,
+                     ProcessState::NONEXISTENT});
+  return *kCachedStates;
+}
 
 ArcProcess::ArcProcess(base::ProcessId nspid,
                        base::ProcessId pid,
@@ -80,21 +90,21 @@
 ArcProcess& ArcProcess::operator=(ArcProcess&& other) = default;
 
 bool ArcProcess::IsImportant() const {
-  return kImportantStates.count(process_state()) == 1 || IsArcProtected();
+  return ImportantStates().count(process_state()) == 1 || IsArcProtected();
 }
 
 bool ArcProcess::IsPersistent() const {
   // Protect PERSISTENT, PERSISTENT_UI, our HOME and custom set of ARC processes
   // since they should have lower priority to be killed.
-  return kPersistentStates.count(process_state()) == 1 || IsArcProtected();
+  return PersistentStates().count(process_state()) == 1 || IsArcProtected();
 }
 
 bool ArcProcess::IsCached() const {
-  return kCachedStates.count(process_state()) == 1;
+  return CachedStates().count(process_state()) == 1;
 }
 
 bool ArcProcess::IsBackgroundProtected() const {
-  return kProtectedBackgroundStates.count(process_state()) == 1;
+  return ProtectedBackgroundStates().count(process_state()) == 1;
 }
 
 bool ArcProcess::IsArcProtected() const {
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.cc b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
index 0bd0736..e725cea 100644
--- a/chrome/browser/chromeos/crostini/crostini_registry_service.cc
+++ b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
@@ -9,6 +9,7 @@
 #include "ash/public/cpp/app_list/app_list_config.h"
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/task/post_task.h"
@@ -66,12 +67,12 @@
   // This is used to deal with the Linux apps that don't specify the correct
   // WMClass in their desktop files so that their aura windows can be identified
   // with their respective app IDs.
-  static const std::map<std::string, std::string> kWMClassToNname = {
-      {"Octave-gui", "GNU Octave"},
-      {"MuseScore2", "MuseScore 2"},
-      {"XnViewMP", "XnView Multi Platform"}};
-  const auto it = kWMClassToNname.find(wmclass.as_string());
-  if (it == kWMClassToNname.end())
+  static const base::NoDestructor<std::map<std::string, std::string>>
+      kWMClassToNname({{"Octave-gui", "GNU Octave"},
+                       {"MuseScore2", "MuseScore 2"},
+                       {"XnViewMP", "XnView Multi Platform"}});
+  const auto it = kWMClassToNname->find(wmclass.as_string());
+  if (it == kWMClassToNname->end())
     return nullptr;
   return &it->second;
 }
diff --git a/chrome/browser/chromeos/extensions/input_method_api.cc b/chrome/browser/chromeos/extensions/input_method_api.cc
index 20c4991..9d2f4e0 100644
--- a/chrome/browser/chromeos/extensions/input_method_api.cc
+++ b/chrome/browser/chromeos/extensions/input_method_api.cc
@@ -31,9 +31,10 @@
 #include "chrome/common/extensions/api/input_method_private.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/constants/chromeos_switches.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "extensions/browser/extension_function_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
@@ -219,13 +220,13 @@
 #if !defined(OS_CHROMEOS)
   EXTENSION_FUNCTION_VALIDATE(false);
 #else
-  browser_sync::ProfileSyncService* profile_sync_service =
-      ProfileSyncServiceFactory::GetForProfile(
+  syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(
           Profile::FromBrowserContext(browser_context()));
-  if (!profile_sync_service)
+  if (!sync_service)
     return RespondNow(Error("Sync service is not ready for current profile."));
   std::unique_ptr<base::Value> ret(new base::Value(
-      profile_sync_service->GetUserSettings()->IsEncryptEverythingEnabled()));
+      sync_service->GetUserSettings()->IsEncryptEverythingEnabled()));
   return RespondNow(OneArgument(std::move(ret)));
 #endif
 }
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
index bd5a4fb..873510e 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -31,8 +31,9 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/constants/chromeos_switches.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -261,13 +262,13 @@
 WallpaperPrivateGetSyncSettingFunction::Run() {
   base::PostTaskWithTraits(
       FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(&WallpaperPrivateGetSyncSettingFunction::
-                         CheckProfileSyncServiceStatus,
-                     this));
+      base::BindOnce(
+          &WallpaperPrivateGetSyncSettingFunction::CheckSyncServiceStatus,
+          this));
   return RespondLater();
 }
 
-void WallpaperPrivateGetSyncSettingFunction::CheckProfileSyncServiceStatus() {
+void WallpaperPrivateGetSyncSettingFunction::CheckSyncServiceStatus() {
   auto dict = std::make_unique<base::DictionaryValue>();
 
   if (retry_number_ > kRetryLimit) {
@@ -280,8 +281,8 @@
   }
 
   Profile* profile =  Profile::FromBrowserContext(browser_context());
-  browser_sync::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+  syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
   if (!sync_service || !sync_service->CanSyncFeatureStart()) {
     // Sync as a whole is disabled.
     dict->SetBoolean(kSyncThemes, false);
@@ -305,9 +306,9 @@
   retry_number_++;
   base::PostDelayedTaskWithTraits(
       FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(&WallpaperPrivateGetSyncSettingFunction::
-                         CheckProfileSyncServiceStatus,
-                     this),
+      base::BindOnce(
+          &WallpaperPrivateGetSyncSettingFunction::CheckSyncServiceStatus,
+          this),
       retry_number_ * kRetryDelay);
 }
 
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.h b/chrome/browser/chromeos/extensions/wallpaper_private_api.h
index 5d2ae661..50ddaee 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.h
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.h
@@ -53,9 +53,9 @@
   ResponseAction Run() override;
 
  private:
-  // Periodically check the profile sync service status until the profile sync
-  // service has configured successfully or hit the retry limit.
-  void CheckProfileSyncServiceStatus();
+  // Periodically check the sync service status until the sync service has
+  // configured successfully or hit the retry limit.
+  void CheckSyncServiceStatus();
 
   // The retry number to check to profile sync service status.
   int retry_number_ = 0;
diff --git a/chrome/browser/chromeos/file_manager/open_with_browser.cc b/chrome/browser/chromeos/file_manager/open_with_browser.cc
index f7d61054..b86e883 100644
--- a/chrome/browser/chromeos/file_manager/open_with_browser.cc
+++ b/chrome/browser/chromeos/file_manager/open_with_browser.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "base/no_destructor.h"
 #include "base/path_service.h"
 #include "base/stl_util.h"
 #include "base/task/post_task.h"
@@ -84,8 +85,9 @@
 bool IsPdfPluginEnabled(Profile* profile) {
   DCHECK(profile);
 
-  static const base::FilePath plugin_path(ChromeContentClient::kPDFPluginPath);
-  return IsPepperPluginEnabled(profile, plugin_path);
+  static const base::NoDestructor<base::FilePath> plugin_path(
+      ChromeContentClient::kPDFPluginPath);
+  return IsPepperPluginEnabled(profile, *plugin_path);
 }
 
 bool IsFlashPluginEnabled(Profile* profile) {
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
index f628bc1..bb8628f4 100644
--- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
+++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
@@ -6,6 +6,7 @@
 
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
+#include "base/no_destructor.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
@@ -29,7 +30,6 @@
 const char kQuickUnlockWhitelistOptionAll[] = "all";
 const char kQuickUnlockWhitelistOptionPin[] = "PIN";
 const char kQuickUnlockWhitelistOptionFingerprint[] = "FINGERPRINT";
-const base::FilePath kFingerprintSensorPath = base::FilePath("/dev/cros_fp");
 
 // Default minimum PIN length. Policy can increase or decrease this value.
 constexpr int kDefaultMinimumPinLength = 6;
@@ -117,7 +117,10 @@
   // Disable fingerprint if the device does not have a fingerprint reader
   // TODO(yulunwu): http://crbug.com/922270
   base::ThreadRestrictions::ScopedAllowIO allow_io;
-  if (!base::PathExists(kFingerprintSensorPath))
+
+  static const base::NoDestructor<base::FilePath> kFingerprintSensorPath(
+      base::FilePath("/dev/cros_fp"));
+  if (!base::PathExists(*kFingerprintSensorPath))
     return false;
 
   // Disable fingerprint if the profile does not belong to the primary user.
diff --git a/chrome/browser/chromeos/login/screens/sync_consent_screen.cc b/chrome/browser/chromeos/login/screens/sync_consent_screen.cc
index 8c560b7..c67110b8 100644
--- a/chrome/browser/chromeos/login/screens/sync_consent_screen.cc
+++ b/chrome/browser/chromeos/login/screens/sync_consent_screen.cc
@@ -14,9 +14,9 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/common/pref_names.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/consent_auditor/consent_auditor.h"
 #include "components/prefs/pref_service.h"
+#include "components/sync/driver/sync_service.h"
 #include "components/user_manager/user_manager.h"
 #include "services/identity/public/cpp/identity_manager.h"
 
@@ -33,9 +33,9 @@
 constexpr base::TimeDelta kSyncConsentSettingsShowDelay =
     base::TimeDelta::FromSeconds(3);
 
-browser_sync::ProfileSyncService* GetSyncService(Profile* profile) {
+syncer::SyncService* GetSyncService(Profile* profile) {
   if (ProfileSyncServiceFactory::HasProfileSyncService(profile))
-    return ProfileSyncServiceFactory::GetForProfile(profile);
+    return ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
   return nullptr;
 }
 
@@ -225,8 +225,7 @@
 bool SyncConsentScreen::IsProfileSyncDisabledByPolicy() const {
   if (test_sync_disabled_by_policy_.has_value())
     return test_sync_disabled_by_policy_.value();
-  const browser_sync::ProfileSyncService* sync_service =
-      GetSyncService(profile_);
+  const syncer::SyncService* sync_service = GetSyncService(profile_);
   return sync_service->HasDisableReason(
       syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
 }
@@ -234,8 +233,7 @@
 bool SyncConsentScreen::IsProfileSyncEngineInitialized() const {
   if (test_sync_engine_initialized_.has_value())
     return test_sync_engine_initialized_.value();
-  const browser_sync::ProfileSyncService* sync_service =
-      GetSyncService(profile_);
+  const syncer::SyncService* sync_service = GetSyncService(profile_);
   return sync_service->IsEngineInitialized();
 }
 
diff --git a/chrome/browser/chromeos/login/signin/auth_sync_observer.cc b/chrome/browser/chromeos/login/signin/auth_sync_observer.cc
index c27b358..5f1abdc5 100644
--- a/chrome/browser/chromeos/login/signin/auth_sync_observer.cc
+++ b/chrome/browser/chromeos/login/signin/auth_sync_observer.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_error_controller_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "components/browser_sync/profile_sync_service.h"
+#include "components/sync/driver/sync_service.h"
 #include "components/user_manager/user_manager.h"
 #include "components/user_manager/user_type.h"
 #include "services/identity/public/cpp/identity_manager.h"
@@ -36,8 +36,8 @@
 AuthSyncObserver::~AuthSyncObserver() {}
 
 void AuthSyncObserver::StartObserving() {
-  browser_sync::ProfileSyncService* const sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  syncer::SyncService* const sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile_);
   if (sync_service)
     sync_service->AddObserver(this);
 
@@ -50,8 +50,8 @@
 }
 
 void AuthSyncObserver::Shutdown() {
-  browser_sync::ProfileSyncService* const sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  syncer::SyncService* const sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile_);
   if (sync_service)
     sync_service->RemoveObserver(this);
 
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 01d5d1b..935f7b8 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -22,6 +22,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
@@ -247,8 +248,9 @@
 
 scoped_refptr<network::SharedURLLoaderFactory>&
 GetSharedURLLoaderFactoryForTesting() {
-  static scoped_refptr<network::SharedURLLoaderFactory> loader;
-  return loader;
+  static base::NoDestructor<scoped_refptr<network::SharedURLLoaderFactory>>
+      loader;
+  return *loader;
 }
 
 }  // namespace
diff --git a/chrome/browser/component_updater/chrome_component_updater_configurator.cc b/chrome/browser/component_updater/chrome_component_updater_configurator.cc
index 31d1b99..daea9ab 100644
--- a/chrome/browser/component_updater/chrome_component_updater_configurator.cc
+++ b/chrome/browser/component_updater/chrome_component_updater_configurator.cc
@@ -28,10 +28,12 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/update_client/activity_data_service.h"
+#include "components/update_client/network.h"
 #include "components/update_client/protocol_handler.h"
 #include "components/update_client/update_query_params.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/service_manager_connection.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/service_manager/public/cpp/connector.h"
 
 #if defined(OS_WIN)
@@ -64,8 +66,8 @@
   std::string GetOSLongName() const override;
   base::flat_map<std::string, std::string> ExtraRequestParams() const override;
   std::string GetDownloadPreference() const override;
-  scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactory()
-      const override;
+  scoped_refptr<update_client::NetworkFetcherFactory> GetNetworkFetcherFactory()
+      override;
   std::unique_ptr<service_manager::Connector> CreateServiceManagerConnector()
       const override;
   bool EnabledDeltas() const override;
@@ -86,6 +88,7 @@
 
   ConfiguratorImpl configurator_impl_;
   PrefService* pref_service_;  // This member is not owned by this class.
+  scoped_refptr<update_client::NetworkFetcherFactory> network_fetcher_factory_;
 
   ~ChromeConfigurator() override {}
 };
@@ -169,14 +172,15 @@
 #endif
 }
 
-scoped_refptr<network::SharedURLLoaderFactory>
-ChromeConfigurator::URLLoaderFactory() const {
-  SystemNetworkContextManager* system_network_context_manager =
-      g_browser_process->system_network_context_manager();
-  // Manager will be null if called from InitializeForTesting.
-  if (!system_network_context_manager)
-    return nullptr;
-  return system_network_context_manager->GetSharedURLLoaderFactory();
+scoped_refptr<update_client::NetworkFetcherFactory>
+ChromeConfigurator::GetNetworkFetcherFactory() {
+  if (!network_fetcher_factory_) {
+    network_fetcher_factory_ =
+        base::MakeRefCounted<update_client::NetworkFetcherFactory>(
+            g_browser_process->system_network_context_manager()
+                ->GetSharedURLLoaderFactory());
+  }
+  return network_fetcher_factory_;
 }
 
 std::unique_ptr<service_manager::Connector>
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 5a4aeff6..27d64b1c 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -960,7 +960,6 @@
     }
     deps += [
       "//ash/public/cpp",
-      "//chrome/browser/resources/chromeos/camera:chrome_camera_app",
       "//chromeos/attestation",
       "//chromeos/components/proximity_auth",
       "//chromeos/cryptohome",
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
index 0abcdfa..f850d1b 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/extensions/extension_function_test_utils.h"
 #include "chrome/browser/policy/browser_dm_token_storage.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.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"
@@ -83,20 +82,15 @@
 class EnterpriseReportingPrivateUploadChromeDesktopReportTest
     : public ExtensionApiUnittest {
  public:
-  EnterpriseReportingPrivateUploadChromeDesktopReportTest()
-      : test_shared_loader_factory_(
-            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-                &test_url_loader_factory_)) {}
-
-  void TearDown() override { test_shared_loader_factory_->Detach(); }
+  EnterpriseReportingPrivateUploadChromeDesktopReportTest() {}
 
   UIThreadExtensionFunction* CreateChromeDesktopReportingFunction(
       const std::string& dm_token) {
     EnterpriseReportingPrivateUploadChromeDesktopReportFunction* function =
         EnterpriseReportingPrivateUploadChromeDesktopReportFunction::
-            CreateForTesting(test_shared_loader_factory_);
-    auto client =
-        std::make_unique<MockCloudPolicyClient>(test_shared_loader_factory_);
+            CreateForTesting(test_url_loader_factory_.GetSafeWeakWrapper());
+    auto client = std::make_unique<MockCloudPolicyClient>(
+        test_url_loader_factory_.GetSafeWeakWrapper());
     client_ = client.get();
     function->SetCloudPolicyClientForTesting(std::move(client));
     function->SetRegistrationInfoForTesting(dm_token, kFakeClientId);
@@ -119,8 +113,6 @@
 
  private:
   network::TestURLLoaderFactory test_url_loader_factory_;
-  scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
-      test_shared_loader_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(
       EnterpriseReportingPrivateUploadChromeDesktopReportTest);
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index fbe27fb..da29d680 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -1542,9 +1542,8 @@
   content::RunAllTasksUntilIdle();  // Flush pending ListAccounts calls.
   signin::SetListAccountsResponseOneAccount(
       account_info.email, account_info.gaia, &test_url_loader_factory_);
-  GaiaCookieManagerService* gcms =
-      GaiaCookieManagerServiceFactory::GetForProfile(profile);
-  gcms->set_list_accounts_stale_for_testing(true);
+  auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
+  identity::SetFreshnessOfAccountsInGaiaCookie(identity_manager, false);
 
   scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
diff --git a/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc b/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc
index 46aa36bb..274405b 100644
--- a/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc
+++ b/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc
@@ -36,7 +36,6 @@
     extension_misc::kSelectToSpeakExtensionId,
     extension_misc::kSwitchAccessExtensionId,
     extension_misc::kZipArchiverExtensionId,
-    extension_misc::kChromeCameraAppId,
 #endif
   };
 
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index a065710..29b9f2c 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/extensions/component_extensions_whitelist/whitelist.h"
 #include "chrome/browser/extensions/data_deleter.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/launch_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/channel_info.h"
@@ -295,17 +294,6 @@
   return false;
 }
 
-void ComponentLoader::AddChromeCameraApp() {
-#if defined(OS_CHROMEOS)
-  base::FilePath resources_path;
-  if (base::PathService::Get(chrome::DIR_RESOURCES, &resources_path)) {
-    AddComponentFromDir(
-        resources_path.Append(extension_misc::kChromeCameraAppPath),
-        extension_misc::kChromeCameraAppId, base::RepeatingClosure());
-  }
-#endif  // defined(OS_CHROMEOS)
-}
-
 void ComponentLoader::AddFileManagerExtension() {
 #if defined(OS_CHROMEOS)
   AddWithNameAndDescription(
@@ -547,7 +535,6 @@
 #endif
 
   if (!skip_session_components) {
-    AddChromeCameraApp();
     AddVideoPlayerExtension();
     AddAudioPlayerExtension();
     AddFileManagerExtension();
diff --git a/chrome/browser/extensions/component_loader.h b/chrome/browser/extensions/component_loader.h
index 287069b..8a78a56 100644
--- a/chrome/browser/extensions/component_loader.h
+++ b/chrome/browser/extensions/component_loader.h
@@ -177,7 +177,6 @@
   void AddChromeApp();
   void AddKeyboardApp();
   void AddWebStoreApp();
-  void AddChromeCameraApp();
 
   scoped_refptr<const Extension> CreateExtension(
       const ComponentExtensionInfo& info, std::string* utf8_error);
diff --git a/chrome/browser/extensions/external_pref_loader.cc b/chrome/browser/extensions/external_pref_loader.cc
index 516720f0..0315d62 100644
--- a/chrome/browser/extensions/external_pref_loader.cc
+++ b/chrome/browser/extensions/external_pref_loader.cc
@@ -27,8 +27,9 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/common/chrome_paths.h"
-#include "components/browser_sync/profile_sync_service.h"
+#include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_service_observer.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "components/sync_preferences/pref_service_syncable.h"
 #include "components/sync_preferences/pref_service_syncable_observer.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -101,8 +102,8 @@
     }
     // Start observing sync changes.
     DCHECK(profile_);
-    browser_sync::ProfileSyncService* service =
-        ProfileSyncServiceFactory::GetForProfile(profile_);
+    syncer::SyncService* service =
+        ProfileSyncServiceFactory::GetSyncServiceForProfile(profile_);
     DCHECK(service);
     if (service->CanSyncFeatureStart() &&
         (service->GetUserSettings()->IsFirstSetupComplete() ||
@@ -146,8 +147,8 @@
     DCHECK(prefs);
     syncable_pref_observer_.Add(prefs);
 
-    browser_sync::ProfileSyncService* service =
-        ProfileSyncServiceFactory::GetForProfile(profile_);
+    syncer::SyncService* service =
+        ProfileSyncServiceFactory::GetSyncServiceForProfile(profile_);
     sync_service_observer_.Add(service);
   }
 
@@ -161,7 +162,7 @@
   ScopedObserver<sync_preferences::PrefServiceSyncable,
                  sync_preferences::PrefServiceSyncableObserver>
       syncable_pref_observer_;
-  ScopedObserver<browser_sync::ProfileSyncService, syncer::SyncServiceObserver>
+  ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver>
       sync_service_observer_;
 
   DISALLOW_COPY_AND_ASSIGN(PrioritySyncReadyWaiter);
diff --git a/chrome/browser/extensions/plugin_manager.cc b/chrome/browser/extensions/plugin_manager.cc
index 962415f4..22af31a 100644
--- a/chrome/browser/extensions/plugin_manager.cc
+++ b/chrome/browser/extensions/plugin_manager.cc
@@ -6,6 +6,7 @@
 
 #include "base/files/file_path.h"
 #include "base/lazy_instance.h"
+#include "base/no_destructor.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
@@ -140,9 +141,10 @@
   // there is a MIME type that module wants to handle, so we need to add that
   // MIME type to plugins which handle NaCl modules in order to allow the
   // individual modules to handle these types.
-  static const base::FilePath path(ChromeContentClient::kNaClPluginFileName);
+  static const base::NoDestructor<base::FilePath> path(
+      ChromeContentClient::kNaClPluginFileName);
   const content::PepperPluginInfo* pepper_info =
-      PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(path);
+      PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(*path);
   if (!pepper_info)
     return;
 
diff --git a/chrome/browser/extensions/updater/chrome_update_client_config.cc b/chrome/browser/extensions/updater/chrome_update_client_config.cc
index 099099b..a915f36 100644
--- a/chrome/browser/extensions/updater/chrome_update_client_config.cc
+++ b/chrome/browser/extensions/updater/chrome_update_client_config.cc
@@ -17,6 +17,7 @@
 #include "chrome/common/channel_info.h"
 #include "components/prefs/pref_service.h"
 #include "components/update_client/activity_data_service.h"
+#include "components/update_client/network.h"
 #include "components/update_client/protocol_handler.h"
 #include "components/update_client/update_query_params.h"
 #include "content/public/browser/browser_context.h"
@@ -165,10 +166,15 @@
   return std::string();
 }
 
-scoped_refptr<network::SharedURLLoaderFactory>
-ChromeUpdateClientConfig::URLLoaderFactory() const {
-  return content::BrowserContext::GetDefaultStoragePartition(context_)
-      ->GetURLLoaderFactoryForBrowserProcess();
+scoped_refptr<update_client::NetworkFetcherFactory>
+ChromeUpdateClientConfig::GetNetworkFetcherFactory() {
+  if (!network_fetcher_factory_) {
+    network_fetcher_factory_ =
+        base::MakeRefCounted<update_client::NetworkFetcherFactory>(
+            content::BrowserContext::GetDefaultStoragePartition(context_)
+                ->GetURLLoaderFactoryForBrowserProcess());
+  }
+  return network_fetcher_factory_;
 }
 
 std::unique_ptr<service_manager::Connector>
diff --git a/chrome/browser/extensions/updater/chrome_update_client_config.h b/chrome/browser/extensions/updater/chrome_update_client_config.h
index 27bc4ff..7ab55b8 100644
--- a/chrome/browser/extensions/updater/chrome_update_client_config.h
+++ b/chrome/browser/extensions/updater/chrome_update_client_config.h
@@ -23,6 +23,7 @@
 
 namespace update_client {
 class ActivityDataService;
+class NetworkFetcherFactory;
 class ProtocolHandlerFactory;
 }
 
@@ -53,8 +54,8 @@
   std::string GetOSLongName() const override;
   base::flat_map<std::string, std::string> ExtraRequestParams() const override;
   std::string GetDownloadPreference() const override;
-  scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactory()
-      const override;
+  scoped_refptr<update_client::NetworkFetcherFactory> GetNetworkFetcherFactory()
+      override;
   std::unique_ptr<service_manager::Connector> CreateServiceManagerConnector()
       const override;
   bool EnabledDeltas() const override;
@@ -87,6 +88,7 @@
   component_updater::ConfiguratorImpl impl_;
   PrefService* pref_service_;
   std::unique_ptr<update_client::ActivityDataService> activity_data_service_;
+  scoped_refptr<update_client::NetworkFetcherFactory> network_fetcher_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeUpdateClientConfig);
 };
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
index a80201f2..6a943ceb 100644
--- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
+++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -20,9 +20,9 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/pref_names.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/prefs/pref_service.h"
 #include "components/sync/driver/about_sync_util.h"
+#include "components/sync/driver/sync_service.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/api/power/power_api.h"
 #include "extensions/browser/extension_registry.h"
@@ -269,12 +269,11 @@
 void ChromeInternalLogSource::PopulateSyncLogs(SystemLogsResponse* response) {
   // We are only interested in sync logs for the primary user profile.
   Profile* profile = ProfileManager::GetPrimaryUserProfile();
-  if (!profile ||
-      !ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(profile))
+  if (!profile || !ProfileSyncServiceFactory::HasProfileSyncService(profile))
     return;
 
-  browser_sync::ProfileSyncService* service =
-      ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
+  syncer::SyncService* service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
   std::unique_ptr<base::DictionaryValue> sync_logs(
       syncer::sync_ui_util::ConstructAboutInformation(service,
                                                       chrome::GetChannel()));
diff --git a/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc
index 89b6f15..c3588c3e 100644
--- a/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc
+++ b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc
@@ -88,18 +88,10 @@
 
   content::StoragePartition* storage_partition =
       content::BrowserContext::GetDefaultStoragePartition(context);
-  std::unique_ptr<unified_consent::UrlKeyedDataCollectionConsentHelper>
-      consent_helper;
-  if (unified_consent::IsUnifiedConsentFeatureEnabled()) {
-    consent_helper = unified_consent::UrlKeyedDataCollectionConsentHelper::
-        NewPersonalizedDataCollectionConsentHelper(
-            ProfileSyncServiceFactory::GetSyncServiceForProfile(profile));
-  }
-
   auto contextual_suggestions_fetcher =
       std::make_unique<ContextualSuggestionsFetcherImpl>(
           storage_partition->GetURLLoaderFactoryForBrowserProcess(),
-          std::move(consent_helper), g_browser_process->GetApplicationLocale());
+          g_browser_process->GetApplicationLocale());
   auto reporter_provider = std::make_unique<
       contextual_suggestions::ContextualSuggestionsReporterProvider>(
       std::make_unique<
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index a72cf34..735cfcf 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -37,7 +37,6 @@
 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/autofill/core/common/password_generation_util.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/password_manager/content/browser/bad_message.h"
 #include "components/password_manager/content/browser/content_password_manager_driver.h"
 #include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
@@ -122,7 +121,7 @@
 
 const syncer::SyncService* GetSyncService(Profile* profile) {
   if (ProfileSyncServiceFactory::HasProfileSyncService(profile))
-    return ProfileSyncServiceFactory::GetForProfile(profile);
+    return ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
   return nullptr;
 }
 
@@ -564,8 +563,8 @@
 
 password_manager::SyncState ChromePasswordManagerClient::GetPasswordSyncState()
     const {
-  const browser_sync::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  const syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile_);
   return password_manager_util::GetPasswordSyncState(sync_service);
 }
 
@@ -799,10 +798,10 @@
   if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled())
     return false;
 
-  browser_sync::ProfileSyncService* profile_sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
-  if (!profile_sync_service || !profile_sync_service->IsSyncFeatureActive() ||
-      profile_sync_service->GetUserSettings()->IsUsingSecondaryPassphrase()) {
+  syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
+  if (!sync_service || !sync_service->IsSyncFeatureActive() ||
+      sync_service->GetUserSettings()->IsUsingSecondaryPassphrase()) {
     return false;
   }
 
diff --git a/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc b/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
index f555d21..829dbd6a0 100644
--- a/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
+++ b/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
@@ -8,6 +8,7 @@
 
 #include "base/feature_list.h"
 #include "base/memory/weak_ptr.h"
+#include "base/no_destructor.h"
 #include "base/task/post_task.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/chrome_features.h"
@@ -79,9 +80,9 @@
 
 #if BUILDFLAG(ENABLE_PLUGINS)
   content::WebPluginInfo pdf_plugin_info;
-  static const base::FilePath pdf_plugin_path(
+  static const base::NoDestructor<base::FilePath> pdf_plugin_path(
       ChromeContentClient::kPDFPluginPath);
-  content::PluginService::GetInstance()->GetPluginInfoByPath(pdf_plugin_path,
+  content::PluginService::GetInstance()->GetPluginInfoByPath(*pdf_plugin_path,
                                                              &pdf_plugin_info);
 
   ChromePluginServiceFilter* filter = ChromePluginServiceFilter::GetInstance();
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc
index 6e42720..ec18ca69 100644
--- a/chrome/browser/printing/print_view_manager.cc
+++ b/chrome/browser/printing/print_view_manager.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/lazy_instance.h"
+#include "base/no_destructor.h"
 #include "build/build_config.h"
 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
 #include "chrome/browser/printing/print_preview_dialog_controller.h"
@@ -38,11 +39,11 @@
 void EnableInternalPDFPluginForContents(int render_process_id,
                                         int render_frame_id) {
   // Always enable the internal PDF plugin for the print preview page.
-  static const base::FilePath pdf_plugin_path(
+  static const base::NoDestructor<base::FilePath> pdf_plugin_path(
       ChromeContentClient::kPDFPluginPath);
   auto* plugin_service = content::PluginService::GetInstance();
   const content::PepperPluginInfo* info =
-      plugin_service->GetRegisteredPpapiPluginInfo(pdf_plugin_path);
+      plugin_service->GetRegisteredPpapiPluginInfo(*pdf_plugin_path);
   if (!info)
     return;
 
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index 8631095..88f97437 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -71,9 +71,8 @@
 #include "chrome/browser/signin/account_fetcher_service_factory.h"
 #include "chrome/browser/signin/account_investigator_factory.h"
 #include "chrome/browser/signin/account_reconcilor_factory.h"
-#include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_profile_attributes_updater_factory.h"
 #include "chrome/browser/sync/model_type_store_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -227,7 +226,6 @@
   AccountFetcherServiceFactory::GetInstance();
   AccountInvestigatorFactory::GetInstance();
   AccountReconcilorFactory::GetInstance();
-  AccountTrackerServiceFactory::GetInstance();
   autofill::PersonalDataManagerFactory::GetInstance();
 #if BUILDFLAG(ENABLE_BACKGROUND_CONTENTS)
   BackgroundContentsServiceFactory::GetInstance();
@@ -292,6 +290,7 @@
   GoogleURLTrackerFactory::GetInstance();
   HistoryServiceFactory::GetInstance();
   HostContentSettingsMapFactory::GetInstance();
+  IdentityManagerFactory::EnsureFactoryAndDependeeFactoriesBuilt();
   InMemoryURLIndexFactory::GetInstance();
   invalidation::DeprecatedProfileInvalidationProviderFactory::GetInstance();
 #if !defined(OS_ANDROID)
@@ -378,7 +377,6 @@
   SessionServiceFactory::GetInstance();
 #endif
   ShortcutsBackendFactory::GetInstance();
-  SigninManagerFactory::GetInstance();
   SigninProfileAttributesUpdaterFactory::GetInstance();
 
   if (SiteEngagementService::IsEnabled())
diff --git a/chrome/browser/resources/chromeos/camera/BUILD.gn b/chrome/browser/resources/chromeos/camera/BUILD.gn
deleted file mode 100644
index 1acc259..0000000
--- a/chrome/browser/resources/chromeos/camera/BUILD.gn
+++ /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.
-
-chrome_camera_app_dir = "$root_out_dir/resources/chromeos/camera"
-
-group("chrome_camera_app") {
-  deps = [
-    ":chrome_camera_app_base",
-    "//chrome/browser/resources/chromeos/camera/src/strings:camera_strings",
-  ]
-}
-
-copy("chrome_camera_app_base") {
-  sources = [
-    "src/css",
-    "src/images",
-    "src/js",
-    "src/manifest.json",
-    "src/sounds",
-    "src/views",
-  ]
-
-  outputs = [
-    "$chrome_camera_app_dir/{{source_file_part}}",
-  ]
-}
diff --git a/chrome/browser/resources/chromeos/camera/Makefile b/chrome/browser/resources/chromeos/camera/Makefile
index 4cd0bfe..66061773 100644
--- a/chrome/browser/resources/chromeos/camera/Makefile
+++ b/chrome/browser/resources/chromeos/camera/Makefile
@@ -116,6 +116,7 @@
 	src/js/models/file_system.js \
 	src/js/nav.js \
 	src/js/scrollbar.js \
+	src/js/sound.js \
 	src/js/toast.js \
 	src/js/tooltip.js \
 	src/js/util.js \
diff --git a/chrome/browser/resources/chromeos/camera/src/css/main.css b/chrome/browser/resources/chromeos/camera/src/css/main.css
index 41a93b8..6e9318d 100644
--- a/chrome/browser/resources/chromeos/camera/src/css/main.css
+++ b/chrome/browser/resources/chromeos/camera/src/css/main.css
@@ -6,6 +6,10 @@
   height: 100%;  /* Required for printing. */
 }
 
+audio {
+  display: none;
+}
+
 body {
   background: black;
   bottom: 0;
diff --git a/chrome/browser/resources/chromeos/camera/src/js/sound.js b/chrome/browser/resources/chromeos/camera/src/js/sound.js
new file mode 100644
index 0000000..87c9980
--- /dev/null
+++ b/chrome/browser/resources/chromeos/camera/src/js/sound.js
@@ -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.
+
+'use strict';
+
+/**
+ * Namespace for the Camera app.
+ */
+var cca = cca || {};
+
+/**
+ * Namespace for sound.
+ */
+cca.sound = cca.sound || {};
+
+/**
+ * Plays a sound.
+ * @param {string} selector Selector of the sound.
+ */
+cca.sound.play = function(selector) {
+  // TODO(yuli): Don't play sounds if the speaker settings is muted.
+  var element = document.querySelector(selector);
+  element.currentTime = 0;
+  element.play();
+  return true;
+};
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
index effcf7c..114c9732 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
@@ -244,8 +244,8 @@
   Promise.resolve(this.ticks_).then(() => {
     // Play a sound before starting to record and delay the take to avoid the
     // sound being recorded if necessary.
-    var delay = (this.recordMode && this.options_.playSound(
-        cca.views.camera.Options.Sound.RECORDSTART)) ? 250 : 0;
+    var delay =
+        (this.recordMode && cca.sound.play('#sound-rec-start')) ? 250 : 0;
     this.takeTimeout_ = setTimeout(() => {
       if (this.recordMode) {
         // Take of recording will be ended by another shutter click.
@@ -287,9 +287,7 @@
       // Play a sound and save the result after a successful take.
       blob.handled = true;
       var recordMode = this.recordMode;
-      this.options_.playSound(recordMode ?
-          cca.views.camera.Options.Sound.RECORDEND :
-          cca.views.camera.Options.Sound.SHUTTER);
+      cca.sound.play(recordMode ? '#sound-rec-end' : '#sound-shutter');
       return this.model_.savePicture(blob, recordMode).catch((error) => {
         cca.toast.show('error_msg_save_file_failed');
         throw error;
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
index c1f9ef5..37faac8 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
@@ -44,30 +44,6 @@
   this.toggleMirror_ = document.querySelector('#toggle-mirror');
 
   /**
-   * @type {Audio}
-   * @private
-   */
-  this.shutterSound_ = document.createElement('audio');
-
-  /**
-   * @type {Audio}
-   * @private
-   */
-  this.tickSound_ = document.createElement('audio');
-
-  /**
-   * @type {Audio}
-   * @private
-   */
-  this.recordStartSound_ = document.createElement('audio');
-
-  /**
-   * @type {Audio}
-   * @private
-   */
-  this.recordEndSound_ = document.createElement('audio');
-
-  /**
    * Device id of the camera device currently used or selected.
    * @type {?string}
    * @private
@@ -117,12 +93,6 @@
   this.toggleMic_.addEventListener('click', () => this.updateAudioByMic_());
   this.toggleMirror_.addEventListener('click', () => this.saveMirroring_());
 
-  // Load the shutter, tick, and recording sound.
-  this.shutterSound_.src = '../sounds/shutter.ogg';
-  this.tickSound_.src = '../sounds/tick.ogg';
-  this.recordStartSound_.src = '../sounds/record_start.ogg';
-  this.recordEndSound_.src = '../sounds/record_end.ogg';
-
   // Restore saved mirroring states per video device.
   chrome.storage.local.get({mirroringToggles: {}},
       (values) => this.mirroringToggles_ = values.mirroringToggles);
@@ -134,17 +104,6 @@
   setInterval(() => this.maybeRefreshVideoDeviceIds_(), 1000);
 };
 
-/**
- * Sounds.
- * @enum {number}
- */
-cca.views.camera.Options.Sound = Object.freeze({
-  SHUTTER: 0,
-  TICK: 1,
-  RECORDSTART: 2,
-  RECORDEND: 3,
-});
-
 cca.views.camera.Options.prototype = {
   get newStreamRequestDisabled() {
     return !document.body.classList.contains('streaming') ||
@@ -207,31 +166,6 @@
 };
 
 /**
- * Handles playing the sound by the speaker option.
- * @param {cca.views.camera.Options.Sound} sound Sound to be played.
- * @return {boolean} Whether the sound being played.
- * TODO(yuli): Move this function into sounds.js.
- */
-cca.views.camera.Options.prototype.playSound = function(sound) {
-  // TODO(yuli): Don't play sounds if the speaker settings is muted.
-  var play = (element) => {
-    element.currentTime = 0;
-    element.play();
-    return true;
-  };
-  switch (sound) {
-    case cca.views.camera.Options.Sound.SHUTTER:
-      return play(this.shutterSound_);
-    case cca.views.camera.Options.Sound.TICK:
-      return play(this.tickSound_);
-    case cca.views.camera.Options.Sound.RECORDSTART:
-      return play(this.recordStartSound_);
-    case cca.views.camera.Options.Sound.RECORDEND:
-      return play(this.recordEndSound_);
-  }
-};
-
-/**
  * Schedules ticks by the timer option if any.
  * @return {?Promise} Promise for the operation.
  * TODO(yuli): Move this function into timerticks.js.
@@ -249,7 +183,7 @@
       if (tickCounter == 0) {
         resolve();
       } else {
-        this.playSound(cca.views.camera.Options.Sound.TICK);
+        cca.sound.play('#sound-tick');
         tickMsg.textContent = tickCounter + '';
         cca.util.animateOnce(tickMsg);
         tickTimeout = setTimeout(onTimerTick, 1000);
diff --git a/chrome/browser/resources/chromeos/camera/src/manifest.json b/chrome/browser/resources/chromeos/camera/src/manifest.json
index b01339e..221569f 100644
--- a/chrome/browser/resources/chromeos/camera/src/manifest.json
+++ b/chrome/browser/resources/chromeos/camera/src/manifest.json
@@ -1,5 +1,4 @@
 {
-  "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3oA1Ox8PiRORjuFDgJeWcwnzZDPHUzuH6fymTrx8KPybhfd6XIYFXvilSsRnsGKPslN+BXke3HWC4/MoB2HM2pNGmsQ+jNyTh2dgk4ISdZYRLfqjxr846/245dkznCJLYAZr72Lk+vRZUyYBcLNNox8jRV5ZF16+8uPPUsUiqbQIDAQAB",
   "manifest_version": 2,
   "name": "__MSG_name__",
   "description": "__MSG_description__",
diff --git a/chrome/browser/resources/chromeos/camera/src/views/main.html b/chrome/browser/resources/chromeos/camera/src/views/main.html
index 8dc02b6f..75c5fa9 100644
--- a/chrome/browser/resources/chromeos/camera/src/views/main.html
+++ b/chrome/browser/resources/chromeos/camera/src/views/main.html
@@ -12,6 +12,7 @@
     <script src="../js/util.js"></script>
     <script src="../js/toast.js"></script>
     <script src="../js/tooltip.js"></script>
+    <script src="../js/sound.js"></script>
     <script src="../js/scrollbar.js"></script>
     <script src="../js/gallerybutton.js"></script>
     <script src="../js/models/gallery.js"></script>
@@ -203,5 +204,9 @@
     </div>
     <div class="centered-overlay" id="toast" aria-live="polite"></div>
     <div id="tooltip" aria-hidden="true"></div>
+    <audio id="sound-tick" src="../sounds/tick.ogg">
+    <audio id="sound-shutter" src="../sounds/shutter.ogg">
+    <audio id="sound-rec-start" src="../sounds/record_start.ogg">
+    <audio id="sound-rec-end" src="../sounds/record_end.ogg">
   </body>
 </html>
diff --git a/chrome/browser/resources/print_preview/new/print_preview_shared_css.html b/chrome/browser/resources/print_preview/new/print_preview_shared_css.html
index 7e29390..7b8ca983 100644
--- a/chrome/browser/resources/print_preview/new/print_preview_shared_css.html
+++ b/chrome/browser/resources/print_preview/new/print_preview_shared_css.html
@@ -11,10 +11,6 @@
         --cr-input-row-container: {
           min-height: 38px;
         };
-        --cr-input-container: {
-          margin-top: 3px;
-          margin-bottom: 3px;
-        };
         --md-select-width: calc(100% - 17px);
         --print-preview-settings-border: 1px solid rgb(232, 234, 237);
         --print-preview-dialog-margin: 34px;
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc
index a7ab2ec..9902737 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc
@@ -411,14 +411,31 @@
   CallRunChromeCleaner();
   run_loop_.Run();
 
+  // Make sure the correct callbacks were invoked whether the process exited
+  // normally or through a Mojo connection error handler.
   EXPECT_TRUE(on_process_done_called_);
   EXPECT_TRUE(on_connection_closed_called_);
-  EXPECT_EQ(on_prompt_user_called_,
-            (cleaner_process_options_.crash_point() ==
-                 MockChromeCleanerProcess::CrashPoint::kNone ||
-             cleaner_process_options_.crash_point() ==
-                 MockChromeCleanerProcess::CrashPoint::kAfterResponseReceived));
 
+  // Check whether the prompt was shown.
+  switch (cleaner_process_options_.crash_point()) {
+    case MockChromeCleanerProcess::CrashPoint::kNone:
+    case MockChromeCleanerProcess::CrashPoint::kAfterResponseReceived:
+      EXPECT_TRUE(on_prompt_user_called_);
+      break;
+    case MockChromeCleanerProcess::CrashPoint::kOnStartup:
+    case MockChromeCleanerProcess::CrashPoint::kAfterConnection:
+      EXPECT_FALSE(on_prompt_user_called_);
+      break;
+    case MockChromeCleanerProcess::CrashPoint::kAfterRequestSent:
+      // The child process crashes while the request is in-flight, so
+      // OnPromptUser may or may not be called depending on timing.
+      break;
+    default:
+      FAIL() << "Invalid crash point";
+      break;
+  }
+
+  // If the prompt was shown, validate its contents.
   if (on_prompt_user_called_ &&
       !cleaner_process_options_.files_to_delete().empty()) {
     EXPECT_THAT(
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc
index 5d194f4..37a84295 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc
@@ -11,11 +11,11 @@
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
 #include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/threading/thread.h"
 #include "base/values.h"
@@ -363,7 +363,7 @@
   if (options_.crash_point() == CrashPoint::kAfterConnection)
     exit(kDeliberateCrashExitCode);
 
-  base::MessageLoop message_loop;
+  base::test::ScopedTaskEnvironment scoped_task_environment;
   base::RunLoop run_loop;
   // After the response from the parent process is received, this will post a
   // task to unblock the child process's main thread.
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
index a690db0..0d10a51 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -32,7 +32,6 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/google/core/common/google_util.h"
 #include "components/password_manager/core/browser/hash_password_manager.h"
@@ -51,6 +50,7 @@
 #include "components/safe_browsing/web_ui/safe_browsing_ui.h"
 #include "components/signin/core/browser/account_info.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/sync/driver/sync_service.h"
 #include "components/sync/protocol/user_event_specifics.pb.h"
 #include "components/sync/user_events/user_event_service.h"
 #include "content/public/browser/browser_thread.h"
@@ -627,8 +627,8 @@
 }
 
 bool ChromePasswordProtectionService::IsHistorySyncEnabled() {
-  browser_sync::ProfileSyncService* sync =
-      ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
+  syncer::SyncService* sync =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile_);
   return sync && sync->IsSyncFeatureActive() && !sync->IsLocalSyncEnabled() &&
          sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES);
 }
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index 254ec59..c2a362f3 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -909,17 +909,18 @@
   return base_session_service_.get();
 }
 
-void SessionService::SetAvailableRangeForTest(const SessionID& tab_id,
-                                              const std::pair<int, int> range) {
+void SessionService::SetAvailableRangeForTest(
+    const SessionID& tab_id,
+    const std::pair<int, int>& range) {
   tab_to_available_range_[tab_id] = range;
 }
 
 bool SessionService::GetAvailableRangeForTest(const SessionID& tab_id,
-                                              std::pair<int, int>& range) {
+                                              std::pair<int, int>* range) {
   auto i = tab_to_available_range_.find(tab_id);
   if (i == tab_to_available_range_.end())
     return false;
 
-  range = i->second;
+  *range = i->second;
   return true;
 }
diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h
index dd63fb9..deea23db 100644
--- a/chrome/browser/sessions/session_service.h
+++ b/chrome/browser/sessions/session_service.h
@@ -327,9 +327,9 @@
   sessions::BaseSessionService* GetBaseSessionServiceForTest();
 
   void SetAvailableRangeForTest(const SessionID& tab_id,
-                                const std::pair<int, int> range);
+                                const std::pair<int, int>& range);
   bool GetAvailableRangeForTest(const SessionID& tab_id,
-                                std::pair<int, int>& range);
+                                std::pair<int, int>* range);
 
   // The profile. This may be null during testing.
   Profile* profile_;
diff --git a/chrome/browser/sessions/session_service_test_helper.cc b/chrome/browser/sessions/session_service_test_helper.cc
index b32e2b5f..65b393e 100644
--- a/chrome/browser/sessions/session_service_test_helper.cc
+++ b/chrome/browser/sessions/session_service_test_helper.cc
@@ -124,11 +124,11 @@
 
 void SessionServiceTestHelper::SetAvailableRange(
     const SessionID& tab_id,
-    const std::pair<int, int> range) {
+    const std::pair<int, int>& range) {
   service_->SetAvailableRangeForTest(tab_id, range);
 }
 
 bool SessionServiceTestHelper::GetAvailableRange(const SessionID& tab_id,
-                                                 std::pair<int, int>& range) {
+                                                 std::pair<int, int>* range) {
   return service_->GetAvailableRangeForTest(tab_id, range);
 }
diff --git a/chrome/browser/sessions/session_service_test_helper.h b/chrome/browser/sessions/session_service_test_helper.h
index f2be5ee9..4e869b3 100644
--- a/chrome/browser/sessions/session_service_test_helper.h
+++ b/chrome/browser/sessions/session_service_test_helper.h
@@ -85,8 +85,8 @@
                               const base::Closure& task);
 
   void SetAvailableRange(const SessionID& tab_id,
-                         const std::pair<int, int> range);
-  bool GetAvailableRange(const SessionID& tab_id, std::pair<int, int>& range);
+                         const std::pair<int, int>& range);
+  bool GetAvailableRange(const SessionID& tab_id, std::pair<int, int>* range);
 
  private:
   std::unique_ptr<SessionService> service_;
diff --git a/chrome/browser/sessions/session_service_unittest.cc b/chrome/browser/sessions/session_service_unittest.cc
index f4fa62a..d68a6476 100644
--- a/chrome/browser/sessions/session_service_unittest.cc
+++ b/chrome/browser/sessions/session_service_unittest.cc
@@ -280,7 +280,7 @@
                                      3 /* count */);
 
   std::pair<int, int> available_range;
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(0, available_range.first);
   EXPECT_EQ(2, available_range.second);
 
@@ -642,7 +642,7 @@
                                              2 /* count */);
 
   std::pair<int, int> available_range;
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(0, available_range.first);
   EXPECT_EQ(2, available_range.second);
 
@@ -694,7 +694,7 @@
                                              2 /* count */);
 
   std::pair<int, int> available_range;
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(0, available_range.first);
   EXPECT_EQ(2, available_range.second);
 
@@ -737,7 +737,7 @@
                                              2 /* count */);
 
   std::pair<int, int> available_range;
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(2, available_range.first);
   EXPECT_EQ(5, available_range.second);
 
@@ -747,7 +747,7 @@
   // 2. Test when range is before the pruned entries.
   helper_.service()->TabNavigationPathPruned(window_id, tab_id, 8 /* index */,
                                              2 /* count */);
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(4, available_range.first);
   EXPECT_EQ(7, available_range.second);
 
@@ -757,7 +757,7 @@
   // 3. Test when range is within the pruned entries.
   helper_.service()->TabNavigationPathPruned(window_id, tab_id, 3 /* index */,
                                              5 /* count */);
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(0, available_range.first);
   EXPECT_EQ(0, available_range.second);
 
@@ -767,7 +767,7 @@
   // 4. Test when only range.first is within the pruned entries.
   helper_.service()->TabNavigationPathPruned(window_id, tab_id, 3 /* index */,
                                              3 /* count */);
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(3, available_range.first);
   EXPECT_EQ(4, available_range.second);
 
@@ -777,7 +777,7 @@
   // 4. Test when only range.second is within the pruned entries.
   helper_.service()->TabNavigationPathPruned(window_id, tab_id, 5 /* index */,
                                              3 /* count */);
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(4, available_range.first);
   EXPECT_EQ(4, available_range.second);
 
@@ -787,7 +787,7 @@
   // 4. Test when only range contains all the pruned entries.
   helper_.service()->TabNavigationPathPruned(window_id, tab_id, 5 /* index */,
                                              2 /* count */);
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(4, available_range.first);
   EXPECT_EQ(5, available_range.second);
 }
@@ -816,7 +816,7 @@
                                              5 /* count */);
 
   std::pair<int, int> available_range;
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(0, available_range.first);
   EXPECT_EQ(0, available_range.second);
 
@@ -1052,7 +1052,7 @@
                                              5 /* count */);
 
   std::pair<int, int> available_range;
-  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, available_range));
+  EXPECT_TRUE(helper_.GetAvailableRange(tab_id, &available_range));
   EXPECT_EQ(0, available_range.first);
   EXPECT_EQ(0, available_range.second);
 
diff --git a/chrome/browser/signin/chrome_signin_client_unittest.cc b/chrome/browser/signin/chrome_signin_client_unittest.cc
index aa258051..112b2d30 100644
--- a/chrome/browser/signin/chrome_signin_client_unittest.cc
+++ b/chrome/browser/signin/chrome_signin_client_unittest.cc
@@ -20,7 +20,6 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/signin/core/browser/account_consistency_method.h"
-#include "components/signin/core/browser/signin_manager.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "services/network/test/test_network_connection_tracker.h"
@@ -137,10 +136,9 @@
   MOCK_METHOD1(ShowUserManager, void(const base::FilePath&));
   MOCK_METHOD1(LockForceSigninProfile, void(const base::FilePath&));
 
-  MOCK_METHOD4(SignOutCallback,
+  MOCK_METHOD3(SignOutCallback,
                void(signin_metrics::ProfileSignout,
                     signin_metrics::SignoutDelete,
-                    SigninManager::RemoveAccountsOption remove_option,
                     SigninClient::SignoutDecision signout_decision));
 };
 
@@ -164,12 +162,10 @@
 
   void PreSignOut(signin_metrics::ProfileSignout source_metric,
                   signin_metrics::SignoutDelete delete_metric) {
-    client_->PreSignOut(
-        base::BindOnce(&MockChromeSigninClient::SignOutCallback,
-                       base::Unretained(client_.get()), source_metric,
-                       delete_metric,
-                       SigninManager::RemoveAccountsOption::kRemoveAllAccounts),
-        source_metric);
+    client_->PreSignOut(base::BindOnce(&MockChromeSigninClient::SignOutCallback,
+                                       base::Unretained(client_.get()),
+                                       source_metric, delete_metric),
+                        source_metric);
   }
 
   std::unique_ptr<MockChromeSigninClient> client_;
@@ -188,7 +184,6 @@
   EXPECT_CALL(
       *client_,
       SignOutCallback(source_metric, delete_metric,
-                      SigninManager::RemoveAccountsOption::kRemoveAllAccounts,
                       SigninClient::SignoutDecision::ALLOW_SIGNOUT))
       .Times(1);
 
@@ -212,7 +207,6 @@
   EXPECT_CALL(
       *client_,
       SignOutCallback(source_metric, delete_metric,
-                      SigninManager::RemoveAccountsOption::kRemoveAllAccounts,
                       SigninClient::SignoutDecision::ALLOW_SIGNOUT))
       .Times(1);
 
@@ -227,7 +221,6 @@
   EXPECT_CALL(
       *client_,
       SignOutCallback(source_metric, delete_metric,
-                      SigninManager::RemoveAccountsOption::kRemoveAllAccounts,
                       SigninClient::SignoutDecision::ALLOW_SIGNOUT))
       .Times(1);
   PreSignOut(source_metric, delete_metric);
@@ -249,7 +242,6 @@
   EXPECT_CALL(
       *client_,
       SignOutCallback(source_metric, delete_metric,
-                      SigninManager::RemoveAccountsOption::kRemoveAllAccounts,
                       SigninClient::SignoutDecision::ALLOW_SIGNOUT))
       .Times(1);
   PreSignOut(source_metric, delete_metric);
@@ -309,7 +301,6 @@
   EXPECT_CALL(
       *client_,
       SignOutCallback(signout_source, delete_metric,
-                      SigninManager::RemoveAccountsOption::kRemoveAllAccounts,
                       SigninClient::SignoutDecision::ALLOW_SIGNOUT))
       .Times(1);
 
@@ -338,11 +329,8 @@
           : SigninClient::SignoutDecision::ALLOW_SIGNOUT;
   signin_metrics::SignoutDelete delete_metric =
       signin_metrics::SignoutDelete::IGNORE_METRIC;
-  EXPECT_CALL(
-      *client_,
-      SignOutCallback(signout_source, delete_metric,
-                      SigninManager::RemoveAccountsOption::kRemoveAllAccounts,
-                      signout_decision))
+  EXPECT_CALL(*client_,
+              SignOutCallback(signout_source, delete_metric, signout_decision))
       .Times(1);
 
   PreSignOut(signout_source, delete_metric);
diff --git a/chrome/browser/signin/gaia_cookie_manager_service_test_util.h b/chrome/browser/signin/gaia_cookie_manager_service_test_util.h
index 1bbdac5..bc5fd45 100644
--- a/chrome/browser/signin/gaia_cookie_manager_service_test_util.h
+++ b/chrome/browser/signin/gaia_cookie_manager_service_test_util.h
@@ -23,17 +23,4 @@
     network::TestURLLoaderFactory* test_url_loader_factory,
     content::BrowserContext* context);
 
-// Builds a FakeGaiaCookieManagerService which uses the provided
-// |test_url_loader_factory| for cookie-related requests.
-//
-// TODO(https://crbug.com/907782): Convert all test code to use
-// GaiaCookieManagerService directly, passing a TestURLLoaderFactory when
-// fakes are needed.
-//
-// Once that's done, the method below can be deleted, and this file can be
-// renamed to something like gaia_cookie_manager_service_test_util.cc
-std::unique_ptr<KeyedService> BuildFakeGaiaCookieManagerServiceWithURLLoader(
-    network::TestURLLoaderFactory* test_url_loader_factory,
-    content::BrowserContext* context);
-
-#endif  // CHROME_BROWSER_SIGNIN_FAKE_GAIA_COOKIE_MANAGER_SERVICE_BUILDER_H_
+#endif  // CHROME_BROWSER_SIGNIN_GAIA_COOKIE_MANAGER_SERVICE_TEST_UTIL_H_
diff --git a/chrome/browser/signin/identity_manager_factory.cc b/chrome/browser/signin/identity_manager_factory.cc
index 741664f..4da6fa5 100644
--- a/chrome/browser/signin/identity_manager_factory.cc
+++ b/chrome/browser/signin/identity_manager_factory.cc
@@ -114,6 +114,15 @@
 }
 
 // static
+void IdentityManagerFactory::EnsureFactoryAndDependeeFactoriesBuilt() {
+  IdentityManagerFactory::GetInstance();
+  AccountTrackerServiceFactory::GetInstance();
+  GaiaCookieManagerServiceFactory::GetInstance();
+  ProfileOAuth2TokenServiceFactory::GetInstance();
+  SigninManagerFactory::GetInstance();
+}
+
+// static
 std::unique_ptr<KeyedService>
 IdentityManagerFactory::BuildAuthenticatedServiceInstanceForTesting(
     const std::string& gaia_id,
diff --git a/chrome/browser/signin/identity_manager_factory.h b/chrome/browser/signin/identity_manager_factory.h
index 871024f..8fcb85f3 100644
--- a/chrome/browser/signin/identity_manager_factory.h
+++ b/chrome/browser/signin/identity_manager_factory.h
@@ -44,6 +44,10 @@
   // Returns an instance of the IdentityManagerFactory singleton.
   static IdentityManagerFactory* GetInstance();
 
+  // Ensures that IdentityManagerFactory and the factories on which it depends
+  // are built.
+  static void EnsureFactoryAndDependeeFactoriesBuilt();
+
   // Exposes BuildServiceInstanceFor() publicly for usage to unittests,
   // returning an authenticated IdentityManager, useful specially in
   // ChromeOS scenarios.
diff --git a/chrome/browser/signin/signin_util_win.cc b/chrome/browser/signin/signin_util_win.cc
index 5593c3e..2dfb67b 100644
--- a/chrome/browser/signin/signin_util_win.cc
+++ b/chrome/browser/signin/signin_util_win.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/no_destructor.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/registry.h"
 #include "base/win/win_util.h"
@@ -38,8 +39,9 @@
 
 std::unique_ptr<DiceTurnSyncOnHelper::Delegate>*
 GetDiceTurnSyncOnHelperDelegateForTestingStorage() {
-  static std::unique_ptr<DiceTurnSyncOnHelper::Delegate> delegate;
-  return &delegate;
+  static base::NoDestructor<std::unique_ptr<DiceTurnSyncOnHelper::Delegate>>
+      delegate;
+  return delegate.get();
 }
 
 std::string DecryptRefreshToken(const std::string& cipher_text) {
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 99a7586..9f470af 100644
--- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc
+++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -26,7 +26,6 @@
 #include "chrome/common/pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_user_settings.h"
 #include "content/public/browser/browser_context.h"
diff --git a/chrome/browser/supervised_user/supervised_user_service_factory.cc b/chrome/browser/supervised_user/supervised_user_service_factory.cc
index f094bde..eb35d558 100644
--- a/chrome/browser/supervised_user/supervised_user_service_factory.cc
+++ b/chrome/browser/supervised_user/supervised_user_service_factory.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/supervised_user/supervised_user_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -49,7 +49,7 @@
   DependsOn(
       extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
 #endif
-  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
+  DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(ProfileSyncServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/ui/android/tab_model/tab_model.h b/chrome/browser/ui/android/tab_model/tab_model.h
index ec651ff..ca25f2c 100644
--- a/chrome/browser/ui/android/tab_model/tab_model.h
+++ b/chrome/browser/ui/android/tab_model/tab_model.h
@@ -78,6 +78,8 @@
     FROM_SPECULATIVE_BACKGROUND_CREATION,
     // Opened in the background from Browser Actions context menu.
     FROM_BROWSER_ACTIONS,
+    // Opened by an external application launching a new Chrome incognito tab.
+    FROM_LAUNCH_NEW_INCOGNITO_TAB,
     // Must be last.
     SIZE
   };
diff --git a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.cc b/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.cc
index 950842b..96f1303 100644
--- a/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.cc
+++ b/chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_model_builder.h"
 
+#include "base/no_destructor.h"
 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
 #include "chrome/browser/ui/app_list/plugin_vm/plugin_vm_app_item.h"
 #include "chrome/grit/chrome_unscaled_resources.h"
@@ -21,11 +22,11 @@
 PluginVmAppModelBuilder::~PluginVmAppModelBuilder() = default;
 
 void PluginVmAppModelBuilder::BuildModel() {
-  static const std::string kPluginVmTerminalId =
-      crx_file::id_util::GenerateId(kPluginVmTerminalAppName);
+  static const base::NoDestructor<std::string> kPluginVmTerminalId(
+      crx_file::id_util::GenerateId(kPluginVmTerminalAppName));
   InsertApp(std::make_unique<PluginVmAppItem>(
-      profile(), model_updater(), GetSyncItem(kPluginVmTerminalId),
-      kPluginVmTerminalId, kPluginVmTerminalAppName,
+      profile(), model_updater(), GetSyncItem(*kPluginVmTerminalId),
+      *kPluginVmTerminalId, kPluginVmTerminalAppName,
       ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
           IDR_LOGO_PLUGIN_VM_LAUNCHER)));
 }
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
index f6e005a..bffbdddd 100644
--- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
+++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
@@ -32,10 +32,10 @@
 #include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill/core/common/autofill_prefs.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/core/browser/signin_buildflags.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/sync/driver/sync_service.h"
 #include "components/user_prefs/user_prefs.h"
 #include "content/public/browser/navigation_handle.h"
 #include "services/identity/public/cpp/identity_manager.h"
@@ -283,14 +283,14 @@
                              features::kAutofillSaveCardSignInAfterLocalSave))
     return false;
 
-  const browser_sync::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(GetProfile());
+  const syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(GetProfile());
 
   return !sync_service ||
          sync_service->HasDisableReason(
-             browser_sync::ProfileSyncService::DISABLE_REASON_NOT_SIGNED_IN) ||
+             syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN) ||
          sync_service->HasDisableReason(
-             browser_sync::ProfileSyncService::DISABLE_REASON_USER_CHOICE);
+             syncer::SyncService::DISABLE_REASON_USER_CHOICE);
 }
 
 bool SaveCardBubbleControllerImpl::CanAnimate() const {
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
index 0f271307..28b727b0 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate.h"
 #include "chrome/grit/generated_resources.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/password_manager/core/browser/password_bubble_experiment.h"
 #include "components/password_manager/core/browser/password_form_metrics_recorder.h"
 #include "components/password_manager/core/browser/password_manager_constants.h"
@@ -29,6 +28,7 @@
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/password_manager/core/common/password_manager_ui.h"
 #include "components/prefs/pref_service.h"
+#include "components/sync/driver/sync_service.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -57,8 +57,8 @@
 }
 
 bool IsSyncUser(Profile* profile) {
-  const browser_sync::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+  const syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
   return password_bubble_experiment::IsSmartLockUser(sync_service);
 }
 
@@ -469,8 +469,8 @@
   if (!profile)
     return false;
   PrefService* prefs = profile->GetPrefs();
-  const browser_sync::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+  const syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
   // Signin promotion.
   if (password_bubble_experiment::ShouldShowChromeSignInPasswordPromo(
           prefs, sync_service)) {
diff --git a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
index b47f60b..bf610989 100644
--- a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
@@ -23,12 +23,13 @@
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/autofill/core/common/password_form.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "components/url_formatter/elide_url.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "net/base/url_util.h"
@@ -55,7 +56,7 @@
 
 bool IsSignedInAndSyncingPasswordsNormally(Profile* profile) {
   return password_manager_util::IsSyncingWithNormalEncryption(
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile));
 }
 
 bool IsGooglePasswordManagerEnabled() {
@@ -168,8 +169,8 @@
 }
 
 bool IsSyncingAutosignSetting(Profile* profile) {
-  const browser_sync::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+  const syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
   return (sync_service &&
           sync_service->GetUserSettings()->IsFirstSetupComplete() &&
           sync_service->IsSyncFeatureActive() &&
diff --git a/chrome/browser/ui/passwords/password_dialog_controller_impl.cc b/chrome/browser/ui/passwords/password_dialog_controller_impl.cc
index 7bc3164..ce097c0 100644
--- a/chrome/browser/ui/passwords/password_dialog_controller_impl.cc
+++ b/chrome/browser/ui/passwords/password_dialog_controller_impl.cc
@@ -12,11 +12,11 @@
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/autofill/core/common/password_form.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/password_manager/core/browser/password_bubble_experiment.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/prefs/pref_service.h"
+#include "components/sync/driver/sync_service.h"
 #include "ui/base/l10n/l10n_util.h"
 
 PasswordDialogControllerImpl::PasswordDialogControllerImpl(
@@ -79,8 +79,8 @@
 }
 
 bool PasswordDialogControllerImpl::ShouldShowFooter() const {
-  const browser_sync::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  const syncer::SyncService* sync_service =
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile_);
   return password_bubble_experiment::IsSmartLockUser(sync_service);
 }
 
diff --git a/chrome/browser/ui/recently_audible_helper.cc b/chrome/browser/ui/recently_audible_helper.cc
index c5d0678d..921bde8e 100644
--- a/chrome/browser/ui/recently_audible_helper.cc
+++ b/chrome/browser/ui/recently_audible_helper.cc
@@ -4,13 +4,14 @@
 
 #include "chrome/browser/ui/recently_audible_helper.h"
 
+#include "base/no_destructor.h"
 #include "base/time/default_tick_clock.h"
 
 namespace {
 
 const base::TickClock* GetDefaultTickClock() {
-  static base::DefaultTickClock default_tick_clock;
-  return &default_tick_clock;
+  static base::NoDestructor<base::DefaultTickClock> default_tick_clock;
+  return default_tick_clock.get();
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_sink_button.cc b/chrome/browser/ui/views/media_router/cast_dialog_sink_button.cc
index 4c9e79c..fdff4a6 100644
--- a/chrome/browser/ui/views/media_router/cast_dialog_sink_button.cc
+++ b/chrome/browser/ui/views/media_router/cast_dialog_sink_button.cc
@@ -39,7 +39,7 @@
              int button_tag,
              bool enabled)
       : views::LabelButton(button_listener, base::string16()), owner_(owner) {
-    static const gfx::ImageSkia icon = CreateVectorIcon(
+    const gfx::ImageSkia icon = CreateVectorIcon(
         kGenericStopIcon, kPrimaryIconSize, gfx::kGoogleBlue500);
     SetImage(views::Button::STATE_NORMAL, icon);
     SetInkDropMode(InkDropMode::ON);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
index d77df80..9f9b248 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -314,10 +314,6 @@
   result_view_at(match_index)->OnMatchIconUpdated();
 }
 
-void OmniboxPopupContentsView::PaintUpdatesNow() {
-  // TODO(beng): remove this from the interface.
-}
-
 void OmniboxPopupContentsView::OnDragCanceled() {
   SetMouseHandler(nullptr);
 }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
index afdd98c..f2b6c06 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
@@ -70,7 +70,6 @@
   void OnLineSelected(size_t line) override;
   void UpdatePopupAppearance() override;
   void OnMatchIconUpdated(size_t match_index) override;
-  void PaintUpdatesNow() override;
   void OnDragCanceled() override;
 
   // views::View:
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
index 093d4d9..23f1e98d 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
@@ -160,9 +160,8 @@
 }
 
 const base::string16& OmniboxTextView::text() const {
-  static const base::string16 kEmptyString;
   if (!render_text_)
-    return kEmptyString;
+    return base::EmptyString16();
   return render_text_->text();
 }
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 7d77a9b3..9987f47 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -588,26 +588,18 @@
 
   // If tabbing forwards (shift is not pressed) and suggestion button is not
   // selected, select it.
-  if (model()->popup_model()->SelectedLineHasButton() &&
-      model()->popup_model()->selected_line_state() ==
-          OmniboxPopupModel::NORMAL &&
-      !event.IsShiftDown()) {
-    model()->popup_model()->SetSelectedLineState(
-        OmniboxPopupModel::BUTTON_FOCUSED);
-    popup_view_->ProvideButtonFocusHint(
-        model()->popup_model()->selected_line());
-    return true;
+  if (!event.IsShiftDown()) {
+    if (MaybeFocusTabButton())
+      return true;
   }
 
   // If tabbing backwards (shift is pressed), handle cases involving selecting
   // the tab switch button.
   if (event.IsShiftDown()) {
     // If tab switch button is focused, unfocus it.
-    if (model()->popup_model()->selected_line_state() ==
-        OmniboxPopupModel::BUTTON_FOCUSED) {
-      model()->popup_model()->SetSelectedLineState(OmniboxPopupModel::NORMAL);
+    if (MaybeUnfocusTabButton())
       return true;
-    }
+
     // Otherwise, if at top of results, do nothing.
     if (model()->popup_model()->selected_line() == 0)
       return false;
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
index 01cb670..fe813536 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
@@ -74,7 +74,8 @@
 
 ClearBrowsingDataHandler::ClearBrowsingDataHandler(content::WebUI* webui)
     : profile_(Profile::FromWebUI(webui)),
-      sync_service_(ProfileSyncServiceFactory::GetForProfile(profile_)),
+      sync_service_(
+          ProfileSyncServiceFactory::GetSyncServiceForProfile(profile_)),
       sync_service_observer_(this),
       show_history_deletion_dialog_(false),
       weak_ptr_factory_(this) {}
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
index 96e23993..76d27cb 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
@@ -14,10 +14,10 @@
 #include "base/scoped_observer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "components/browser_sync/profile_sync_service.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/browsing_data/core/counters/browsing_data_counter.h"
 #include "components/signin/core/browser/account_reconcilor.h"
+#include "components/sync/driver/sync_service.h"
 
 namespace base {
 class ListValue;
@@ -92,9 +92,9 @@
   // Counters that calculate the data volume for individual data types.
   std::vector<std::unique_ptr<browsing_data::BrowsingDataCounter>> counters_;
 
-  // ProfileSyncService to observe sync state changes.
-  browser_sync::ProfileSyncService* sync_service_;
-  ScopedObserver<browser_sync::ProfileSyncService, syncer::SyncServiceObserver>
+  // SyncService to observe sync state changes.
+  syncer::SyncService* sync_service_;
+  ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver>
       sync_service_observer_;
 
   // Whether we should show a dialog informing the user about other forms of
diff --git a/chrome/chrome_cleaner/scanner/BUILD.gn b/chrome/chrome_cleaner/scanner/BUILD.gn
index 877b5e8..5ca496a 100644
--- a/chrome/chrome_cleaner/scanner/BUILD.gn
+++ b/chrome/chrome_cleaner/scanner/BUILD.gn
@@ -96,10 +96,12 @@
     ":scanner",
     ":signature_matcher",
     "//base",
+    "//chrome/chrome_cleaner/chrome_utils:chrome_util_lib",
     "//chrome/chrome_cleaner/crash:crash_keys",
     "//chrome/chrome_cleaner/ipc:sandbox",
     "//chrome/chrome_cleaner/logging:common",
     "//chrome/chrome_cleaner/os:common_os",
+    "//chrome/chrome_cleaner/parsers/shortcut_parser/broker:shortcut_parser_api",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/scanner:signature_matcher_api",
     "//chrome/chrome_cleaner/settings:settings",
@@ -115,6 +117,7 @@
   sources = [
     "force_installed_extension_scanner_unittest.cc",
     "matcher_util_unittest.cc",
+    "scanner_controller_unittest.cc",
     "signature_matcher_unittest.cc",
     "urza_scanner_impl_unittest.cc",
   ]
@@ -123,6 +126,7 @@
     ":force_installed_extension_scanner",
     ":force_installed_extension_scanner_api",
     ":matcher_util",
+    ":reporter_scanner",
     ":scanner",
     ":signature_matcher",
     "//base:base",
@@ -130,11 +134,13 @@
     "//chrome/chrome_cleaner/chrome_utils:chrome_util_lib",
     "//chrome/chrome_cleaner/chrome_utils:extension_id",
     "//chrome/chrome_cleaner/constants:common_strings",
+    "//chrome/chrome_cleaner/constants:uws_id",
     "//chrome/chrome_cleaner/logging:common",
     "//chrome/chrome_cleaner/logging:mock_logging_service",
     "//chrome/chrome_cleaner/logging/proto:shared_data_proto",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/shortcut_parser/broker:fake_shortcut_parser",
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
     "//chrome/chrome_cleaner/pup_data:test_uws",
     "//chrome/chrome_cleaner/strings",
@@ -143,6 +149,7 @@
     "//chrome/chrome_cleaner/test:test_strings",
     "//chrome/chrome_cleaner/test:test_util",
     "//chrome/chrome_cleaner/test/resources:test_resources",
+    "//components/chrome_cleaner/public/constants",
     "//components/chrome_cleaner/test:test_name_helper",
     "//sandbox/win:sandbox",
     "//testing/gmock",
diff --git a/chrome/chrome_cleaner/scanner/scanner_controller.cc b/chrome/chrome_cleaner/scanner/scanner_controller.cc
index 8c32d70..35e25ca4 100644
--- a/chrome/chrome_cleaner/scanner/scanner_controller.cc
+++ b/chrome/chrome_cleaner/scanner/scanner_controller.cc
@@ -10,10 +10,12 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
+#include "base/path_service.h"
 #include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "chrome/chrome_cleaner/chrome_utils/chrome_util.h"
 #include "chrome/chrome_cleaner/ipc/sandbox.h"
 #include "chrome/chrome_cleaner/logging/logging_service_api.h"
+#include "chrome/chrome_cleaner/os/file_path_set.h"
 #include "chrome/chrome_cleaner/os/process.h"
 #include "chrome/chrome_cleaner/os/shutdown_watchdog.h"
 #include "chrome/chrome_cleaner/settings/settings.h"
@@ -73,6 +75,44 @@
     watchdog->Arm();
   }
 
+  std::vector<int> keys_of_paths_to_explore = {
+      base::DIR_USER_DESKTOP,      base::DIR_COMMON_DESKTOP,
+      base::DIR_USER_QUICK_LAUNCH, base::DIR_START_MENU,
+      base::DIR_COMMON_START_MENU, base::DIR_TASKBAR_PINS};
+
+  // TODO(proberge): We can move the following code to live inside
+  // FindAndParseChromeShortcutsInFoldersAsync so it can be shared with
+  // SystemReportComponent.
+  std::vector<base::FilePath> paths_to_explore;
+  for (int path_key : keys_of_paths_to_explore) {
+    base::FilePath path;
+    if (base::PathService::Get(path_key, &path))
+      paths_to_explore.push_back(path);
+  }
+
+  if (shortcut_parser_) {
+    std::set<base::FilePath> chrome_exe_paths;
+    ListChromeExePaths(&chrome_exe_paths);
+    FilePathSet chrome_exe_file_path_set;
+    for (const auto& path : chrome_exe_paths)
+      chrome_exe_file_path_set.Insert(path);
+
+    shortcut_parser_->FindAndParseChromeShortcutsInFoldersAsync(
+        paths_to_explore, chrome_exe_file_path_set,
+        base::BindOnce(
+            [](base::WaitableEvent* event,
+               std::vector<ShortcutInformation>* shortcuts_found,
+               std::vector<ShortcutInformation> parsed_shortcuts) {
+              *shortcuts_found = parsed_shortcuts;
+              event->Signal();
+            },
+            &shortcut_parsing_event_, &shortcuts_found_));
+  } else {
+    // If this branch executes it means the shortcut parsing is not enabled
+    // on the command line.
+    shortcut_parsing_event_.Signal();
+  }
+
   base::RunLoop run_loop;
   quit_closure_ = run_loop.QuitWhenIdleClosure();
   StartScan();
@@ -85,9 +125,13 @@
   return static_cast<int>(result_code_);
 }
 
-ScannerController::ScannerController(RegistryLogger* registry_logger)
+ScannerController::ScannerController(RegistryLogger* registry_logger,
+                                     ShortcutParserAPI* shortcut_parser)
     : registry_logger_(registry_logger),
-      watchdog_timeout_in_seconds_(kWatchdogTimeoutInSeconds) {
+      watchdog_timeout_in_seconds_(kWatchdogTimeoutInSeconds),
+      shortcut_parser_(shortcut_parser),
+      shortcut_parsing_event_(base::WaitableEvent::ResetPolicy::MANUAL,
+                              base::WaitableEvent::InitialState::NOT_SIGNALED) {
   DCHECK(registry_logger);
 }
 
@@ -95,6 +139,10 @@
                                      const std::vector<UwSId>& found_pups) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  // Shortcut parsing is done in parallel to the regular scan, if it is not
+  // complete yet, wait for it to finish.
+  shortcut_parsing_event_.Wait();
+
   UpdateScanResults(found_pups);
   if (status == RESULT_CODE_SUCCESS)
     status = GetResultCodeFromFoundUws(found_pups);
@@ -105,6 +153,22 @@
 
   LoggingServiceAPI* logging_service_api = LoggingServiceAPI::GetInstance();
 
+  const base::string16 kChromeExecutableName = L"chrome.exe";
+  bool has_modified_shortcuts = false;
+  for (const auto& shortcut : shortcuts_found_) {
+    base::FilePath target_path(shortcut.target_path);
+
+    // If any of the returned shortcuts is pointing to a file that is not
+    // chrome.exe or that contains arguments report that we found shortcuts
+    // modifications.
+    if (target_path.BaseName().value() != kChromeExecutableName ||
+        !shortcut.command_line_arguments.empty()) {
+      has_modified_shortcuts = true;
+      break;
+    }
+  }
+  logging_service_api->SetFoundModifiedChromeShortcuts(has_modified_shortcuts);
+
   SystemResourceUsage stats;
   if (GetSystemResourceUsage(::GetCurrentProcess(), &stats))
     logging_service_api->LogProcessInformation(SandboxType::kNonSandboxed,
@@ -157,8 +221,7 @@
 
 void ScannerController::LogsUploadComplete(bool success) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                std::move(quit_closure_));
+  std::move(quit_closure_).Run();
 }
 
 }  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/scanner/scanner_controller.h b/chrome/chrome_cleaner/scanner/scanner_controller.h
index a584f676..450c49f3 100644
--- a/chrome/chrome_cleaner/scanner/scanner_controller.h
+++ b/chrome/chrome_cleaner/scanner/scanner_controller.h
@@ -5,15 +5,18 @@
 #ifndef CHROME_CHROME_CLEANER_SCANNER_SCANNER_CONTROLLER_H_
 #define CHROME_CHROME_CLEANER_SCANNER_SCANNER_CONTROLLER_H_
 
+#include <utility>
 #include <vector>
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
-#include "base/message_loop/message_loop.h"
 #include "base/sequence_checker.h"
 #include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
 #include "chrome/chrome_cleaner/constants/uws_id.h"
+#include "chrome/chrome_cleaner/logging/logging_service_api.h"
 #include "chrome/chrome_cleaner/logging/registry_logger.h"
+#include "chrome/chrome_cleaner/parsers/shortcut_parser/broker/shortcut_parser_api.h"
 #include "components/chrome_cleaner/public/constants/result_codes.h"
 
 namespace chrome_cleaner {
@@ -26,7 +29,8 @@
   int ScanOnly();
 
  protected:
-  explicit ScannerController(RegistryLogger* registry_logger);
+  explicit ScannerController(RegistryLogger* registry_logger,
+                             ShortcutParserAPI* shortcut_parser);
 
   virtual void StartScan() = 0;
 
@@ -45,13 +49,14 @@
 
   RegistryLogger* registry_logger_;
   SEQUENCE_CHECKER(sequence_checker_);
-  // Defines a task runner for the current thread, which will be accessible
-  // via base::ThreadTaskRunnerHandle::Get().
-  base::MessageLoopForUI ui_message_loop_;
 
   // Allow subclasses to override the default watchdog timeout.
   uint32_t watchdog_timeout_in_seconds_;
 
+  // Allow subclasses to quit the current run loop without uploading logs.
+  // Should only be called from unit tests.
+  base::OnceClosure QuitClosureForTesting() { return std::move(quit_closure_); }
+
  private:
   // Callback for LoggingServiceAPI::SendLogsToSafeBrowsing() that finishes the
   // current run loop.
@@ -63,6 +68,10 @@
   // Called by LogsUploadComplete() to quit the current run loop.
   base::OnceClosure quit_closure_;
 
+  ShortcutParserAPI* shortcut_parser_;
+  std::vector<ShortcutInformation> shortcuts_found_;
+  base::WaitableEvent shortcut_parsing_event_;
+
   DISALLOW_COPY_AND_ASSIGN(ScannerController);
 };
 
diff --git a/chrome/chrome_cleaner/scanner/scanner_controller_unittest.cc b/chrome/chrome_cleaner/scanner/scanner_controller_unittest.cc
new file mode 100644
index 0000000..21710e7
--- /dev/null
+++ b/chrome/chrome_cleaner/scanner/scanner_controller_unittest.cc
@@ -0,0 +1,233 @@
+// 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/chrome_cleaner/scanner/scanner_controller.h"
+
+#include <windows.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequenced_task_runner.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/task_runner_util.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/test/test_reg_util_win.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/win/registry.h"
+#include "chrome/chrome_cleaner/constants/uws_id.h"
+#include "chrome/chrome_cleaner/logging/registry_logger.h"
+#include "chrome/chrome_cleaner/parsers/shortcut_parser/broker/fake_shortcut_parser.h"
+#include "chrome/chrome_cleaner/pup_data/test_uws.h"
+#include "components/chrome_cleaner/public/constants/constants.h"
+#include "components/chrome_cleaner/public/constants/result_codes.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chrome_cleaner {
+
+namespace {
+
+using ::testing::UnorderedElementsAreArray;
+
+constexpr UwSId kUnknownUwSID = 98765;
+
+class StubScannerController : public ScannerController {
+ public:
+  StubScannerController(RegistryLogger* registry_logger,
+                        ShortcutParserAPI* shortcut_parser)
+      : ScannerController(registry_logger, shortcut_parser) {}
+  ~StubScannerController() override = default;
+
+  void SetResult(ResultCode status) { status_ = status; }
+
+  void SetWatchdogWillTimeout() { watchdog_timeout_ = true; }
+
+  void SetFoundUwS(const std::vector<UwSId>& found_uws) {
+    found_uws_ = found_uws;
+  }
+
+  ResultCode watchdog_result() const { return watchdog_result_; }
+
+ protected:
+  void StartScan() override {
+    scoped_refptr<base::SequencedTaskRunner> task_runner =
+        base::SequencedTaskRunnerHandle::Get();
+    task_runner->PostTask(
+        FROM_HERE, base::BindOnce(&StubScannerController::UpdateScanResults,
+                                  base::Unretained(this), found_uws_));
+
+    if (watchdog_timeout_) {
+      base::PostTaskAndReplyWithResult(
+          task_runner.get(), FROM_HERE,
+          base::BindOnce(&StubScannerController::WatchdogTimeoutCallback,
+                         base::Unretained(this)),
+          base::BindOnce(&StubScannerController::SetWatchdogResult,
+                         base::Unretained(this)));
+
+      // In the real app, the watchdog slays the current process after calling
+      // WatchdogTimeoutCallback. Instead break out of the current test.
+      task_runner->PostTask(FROM_HERE, QuitClosureForTesting());
+      return;
+    }
+
+    task_runner->PostTask(
+        FROM_HERE, base::BindOnce(&StubScannerController::DoneScanning,
+                                  base::Unretained(this), status_, found_uws_));
+  }
+
+  // In the real app the watchdog slays the current process after calling
+  // WatchdogTimeoutCallback, so ScanOnly() never returns with the result code.
+  // Instead store it in a separate member variable that can be checked by the
+  // test.
+  void SetWatchdogResult(ResultCode watchdog_result) {
+    watchdog_result_ = watchdog_result;
+  }
+
+ private:
+  ResultCode status_ = RESULT_CODE_FAILED;
+  std::vector<UwSId> found_uws_;
+  bool watchdog_timeout_ = false;
+
+  ResultCode watchdog_result_ = RESULT_CODE_FAILED;
+};
+
+class ScannerControllerTest : public testing::Test {
+ public:
+  ScannerControllerTest() {
+    registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER);
+    // The registry logger must be created after calling OverrideRegistry.
+    registry_logger_ =
+        std::make_unique<RegistryLogger>(RegistryLogger::Mode::REPORTER);
+  }
+
+  void ExpectFoundUwS(const std::vector<UwSId> found_uws) {
+    std::vector<std::wstring> found_uws_strings;
+    for (const UwSId uws_id : found_uws) {
+      found_uws_strings.push_back(base::NumberToString16(uws_id));
+    }
+
+    base::win::RegKey logging_key(HKEY_CURRENT_USER);
+    ASSERT_EQ(
+        logging_key.OpenKey(kSoftwareRemovalToolRegistryKey, KEY_QUERY_VALUE),
+        ERROR_SUCCESS);
+
+    std::vector<std::wstring> found_uws_value;
+    ASSERT_EQ(logging_key.ReadValues(kFoundUwsValueName, &found_uws_value),
+              ERROR_SUCCESS);
+    EXPECT_THAT(found_uws_value, UnorderedElementsAreArray(found_uws_strings));
+  }
+
+ protected:
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+  registry_util::RegistryOverrideManager registry_override_manager_;
+  std::unique_ptr<RegistryLogger> registry_logger_;
+
+  FakeShortcutParser shortcut_parser_;
+};
+
+TEST_F(ScannerControllerTest, NothingFound) {
+  StubScannerController controller(registry_logger_.get(), &shortcut_parser_);
+  controller.SetResult(RESULT_CODE_SUCCESS);
+
+  EXPECT_EQ(controller.ScanOnly(), RESULT_CODE_NO_PUPS_FOUND);
+  ExpectFoundUwS({});
+}
+
+TEST_F(ScannerControllerTest, ReportOnlyUwSFound) {
+  const std::vector<UwSId> kFoundUwS{kGoogleTestAUwSID};
+
+  StubScannerController controller(registry_logger_.get(), &shortcut_parser_);
+  controller.SetResult(RESULT_CODE_SUCCESS);
+  controller.SetFoundUwS(kFoundUwS);
+
+  EXPECT_EQ(controller.ScanOnly(), RESULT_CODE_REPORT_ONLY_PUPS_FOUND);
+  ExpectFoundUwS(kFoundUwS);
+}
+
+TEST_F(ScannerControllerTest, CleanableUwSFound) {
+  // GoogleTestB is marked cleanable.
+  const std::vector<UwSId> kFoundUwS{kGoogleTestAUwSID, kGoogleTestBUwSID};
+
+  StubScannerController controller(registry_logger_.get(), &shortcut_parser_);
+  controller.SetResult(RESULT_CODE_SUCCESS);
+  controller.SetFoundUwS(kFoundUwS);
+
+  EXPECT_EQ(controller.ScanOnly(), RESULT_CODE_SUCCESS);
+  ExpectFoundUwS(kFoundUwS);
+}
+
+TEST_F(ScannerControllerTest, ErrorWithUwSFound) {
+  const std::vector<UwSId> kFoundUwS{kGoogleTestAUwSID, kGoogleTestBUwSID};
+
+  StubScannerController controller(registry_logger_.get(), &shortcut_parser_);
+  controller.SetResult(RESULT_CODE_FAILED);
+  controller.SetFoundUwS(kFoundUwS);
+
+  EXPECT_EQ(controller.ScanOnly(), RESULT_CODE_FAILED);
+  ExpectFoundUwS(kFoundUwS);
+}
+
+TEST_F(ScannerControllerTest, UnknownUwSFound) {
+  const std::vector<UwSId> kFoundUwS{kGoogleTestAUwSID, kGoogleTestBUwSID,
+                                     kUnknownUwSID};
+
+  StubScannerController controller(registry_logger_.get(), &shortcut_parser_);
+  controller.SetResult(RESULT_CODE_SUCCESS);
+  controller.SetFoundUwS(kFoundUwS);
+
+  EXPECT_EQ(controller.ScanOnly(), RESULT_CODE_ENGINE_REPORTED_UNSUPPORTED_UWS);
+  ExpectFoundUwS(kFoundUwS);
+}
+
+TEST_F(ScannerControllerTest, TimeoutWithNothingFound) {
+  StubScannerController controller(registry_logger_.get(), &shortcut_parser_);
+  controller.SetWatchdogWillTimeout();
+
+  // The return value of ScanOnly isn't used when the watchdog slays the
+  // process.
+  controller.ScanOnly();
+  EXPECT_EQ(controller.watchdog_result(),
+            RESULT_CODE_WATCHDOG_TIMEOUT_WITHOUT_REMOVABLE_UWS);
+  ExpectFoundUwS({});
+}
+
+TEST_F(ScannerControllerTest, TimeoutWithReportOnlyUwSFound) {
+  const std::vector<UwSId> kFoundUwS{kGoogleTestAUwSID};
+
+  StubScannerController controller(registry_logger_.get(), &shortcut_parser_);
+  controller.SetWatchdogWillTimeout();
+  controller.SetFoundUwS(kFoundUwS);
+
+  // The return value of ScanOnly isn't used when the watchdog slays the
+  // process.
+  controller.ScanOnly();
+  EXPECT_EQ(controller.watchdog_result(),
+            RESULT_CODE_WATCHDOG_TIMEOUT_WITHOUT_REMOVABLE_UWS);
+  ExpectFoundUwS(kFoundUwS);
+}
+
+TEST_F(ScannerControllerTest, TimeoutWithCleanableUwSFound) {
+  // GoogleTestB is marked cleanable.
+  const std::vector<UwSId> kFoundUwS{kGoogleTestAUwSID, kGoogleTestBUwSID};
+
+  StubScannerController controller(registry_logger_.get(), &shortcut_parser_);
+  controller.SetWatchdogWillTimeout();
+  controller.SetFoundUwS(kFoundUwS);
+
+  // The return value of ScanOnly isn't used when the watchdog slays the
+  // process.
+  controller.ScanOnly();
+  EXPECT_EQ(controller.watchdog_result(),
+            RESULT_CODE_WATCHDOG_TIMEOUT_WITH_REMOVABLE_UWS);
+  ExpectFoundUwS(kFoundUwS);
+}
+
+}  // namespace
+
+}  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/scanner/urza_scanner_controller.cc b/chrome/chrome_cleaner/scanner/urza_scanner_controller.cc
index 12358210..a037295f 100644
--- a/chrome/chrome_cleaner/scanner/urza_scanner_controller.cc
+++ b/chrome/chrome_cleaner/scanner/urza_scanner_controller.cc
@@ -13,8 +13,9 @@
 UrzaScannerController::UrzaScannerController(
     MatchingOptions* options,
     std::unique_ptr<SignatureMatcherAPI> signature_matcher,
-    RegistryLogger* registry_logger)
-    : ScannerController(registry_logger),
+    RegistryLogger* registry_logger,
+    ShortcutParserAPI* shortcut_parser)
+    : ScannerController(registry_logger, shortcut_parser),
       signature_matcher_(std::move(signature_matcher)),
       scanner_(*options, signature_matcher_.get(), registry_logger) {
   DCHECK(signature_matcher_);
diff --git a/chrome/chrome_cleaner/scanner/urza_scanner_controller.h b/chrome/chrome_cleaner/scanner/urza_scanner_controller.h
index f08a046..a2b95ec 100644
--- a/chrome/chrome_cleaner/scanner/urza_scanner_controller.h
+++ b/chrome/chrome_cleaner/scanner/urza_scanner_controller.h
@@ -9,6 +9,7 @@
 
 #include "chrome/chrome_cleaner/constants/uws_id.h"
 #include "chrome/chrome_cleaner/logging/registry_logger.h"
+#include "chrome/chrome_cleaner/parsers/shortcut_parser/broker/shortcut_parser_api.h"
 #include "chrome/chrome_cleaner/scanner/scanner_controller.h"
 #include "chrome/chrome_cleaner/scanner/signature_matcher_api.h"
 #include "chrome/chrome_cleaner/scanner/urza_scanner_impl.h"
@@ -21,7 +22,8 @@
  public:
   UrzaScannerController(MatchingOptions* options,
                         std::unique_ptr<SignatureMatcherAPI> signature_matcher,
-                        RegistryLogger* registry_logger);
+                        RegistryLogger* registry_logger,
+                        ShortcutParserAPI* shortcut_parser);
   ~UrzaScannerController() override;
 
  protected:
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index fe70300..2307bd7 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -238,7 +238,7 @@
 // Show the number of open incognito windows besides incognito icon on the
 // toolbar.
 const base::Feature kEnableIncognitoWindowCounter{
-    "EnableIncognitoWindowCounter", base::FEATURE_DISABLED_BY_DEFAULT};
+    "EnableIncognitoWindowCounter", base::FEATURE_ENABLED_BY_DEFAULT};
 
 #if defined(OS_CHROMEOS)
 // Enables event-based status reporting for child accounts in Chrome OS.
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index 94d72fe..b3c65002 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -71,7 +71,6 @@
 const char kZipArchiverExtensionId[] = "dmboannefpncccogfdikhmhpmdnddgoe";
 const char kZipArchiverExtensionPath[] = "chromeos/zip_archiver";
 const char kChromeCameraAppId[] = "hfhhnacclhffhdffklopdkcgdhifgngh";
-const char kChromeCameraAppPath[] = "chromeos/camera";
 const char kContainedHomeAppId[] = "nbaolgedfgoedkjbfmpediclncanmpbc";
 #endif
 
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index 4ae3582b..48de342 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -231,8 +231,6 @@
 extern const char kZipArchiverExtensionPath[];
 // The app ID of Chrome camera app.
 extern const char kChromeCameraAppId[];
-// Path to preinstalled Chrome camera app.
-extern const char kChromeCameraAppPath[];
 // The app ID of the contained home app.
 extern const char kContainedHomeAppId[];
 #endif
diff --git a/chrome/test/data/webui/cr_elements/cr_slider_test.js b/chrome/test/data/webui/cr_elements/cr_slider_test.js
index af00b59..a4291d5 100644
--- a/chrome/test/data/webui/cr_elements/cr_slider_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_slider_test.js
@@ -380,4 +380,20 @@
     pressArrowRight();
     return wait;
   });
+
+  test('out of range value updated back into min/max range', () => {
+    crSlider.min = 0;
+    crSlider.max = 100;
+    crSlider.value = 50;
+    assertEquals(50, crSlider.value);
+    crSlider.value = 150;
+    assertEquals(100, crSlider.value);
+    crSlider.value = -50;
+    assertEquals(0, crSlider.value);
+    crSlider.min = 25;
+    assertEquals(25, crSlider.value);
+    crSlider.value = 100;
+    crSlider.max = 50;
+    assertEquals(50, crSlider.value);
+  });
 });
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn
index 189d5466..4134fa1d 100644
--- a/chrome/updater/BUILD.gn
+++ b/chrome/updater/BUILD.gn
@@ -33,6 +33,7 @@
     "//components/version_info",
     "//mojo/core/embedder",
     "//net",
+    "//url",
   ]
 }
 
diff --git a/chrome/updater/configurator.cc b/chrome/updater/configurator.cc
index 9f1cba3..1a34f3c 100644
--- a/chrome/updater/configurator.cc
+++ b/chrome/updater/configurator.cc
@@ -5,9 +5,11 @@
 #include "chrome/updater/configurator.h"
 
 #include "base/version.h"
+#include "components/update_client/network.h"
 #include "components/update_client/protocol_handler.h"
 #include "components/version_info/version_info.h"
 #include "services/service_manager/public/cpp/connector.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -82,8 +84,8 @@
   return {};
 }
 
-scoped_refptr<network::SharedURLLoaderFactory> Configurator::URLLoaderFactory()
-    const {
+scoped_refptr<update_client::NetworkFetcherFactory>
+Configurator::GetNetworkFetcherFactory() {
   return nullptr;
 }
 
diff --git a/chrome/updater/configurator.h b/chrome/updater/configurator.h
index f261af5..d33eede 100644
--- a/chrome/updater/configurator.h
+++ b/chrome/updater/configurator.h
@@ -23,16 +23,13 @@
 class Version;
 }  // namespace base
 
-namespace network {
-class SharedURLLoaderFactory;
-}  // namespace network
-
 namespace service_manager {
 class Connector;
 }  // namespace service_manager
 
 namespace update_client {
 class ActivityDataService;
+class NetworkFetcherFactory;
 class ProtocolHandlerFactory;
 }  // namespace update_client
 
@@ -57,8 +54,8 @@
   std::string GetOSLongName() const override;
   base::flat_map<std::string, std::string> ExtraRequestParams() const override;
   std::string GetDownloadPreference() const override;
-  scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactory()
-      const override;
+  scoped_refptr<update_client::NetworkFetcherFactory> GetNetworkFetcherFactory()
+      override;
   std::unique_ptr<service_manager::Connector> CreateServiceManagerConnector()
       const override;
   bool EnabledDeltas() const override;
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index de8b4839..d66e4e83 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -297,7 +297,6 @@
                         /*identity_manager=*/nullptr,
                         /*client_profile_validator=*/nullptr,
                         /*history_service=*/nullptr,
-                        /*cookie_manager_sevice=*/nullptr,
                         /*is_off_the_record=*/false);
     personal_data_.SetPrefService(autofill_client_.GetPrefs());
 
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc
index 03baf52..8755580 100644
--- a/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -2899,7 +2899,6 @@
                        /*identity_manager=*/nullptr,
                        /*client_profile_validator=*/nullptr,
                        /*history_service=*/nullptr,
-                       /*cookie_manager_sevice=*/nullptr,
                        /*is_off_the_record=*/false);
   histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", true, 1);
 }
@@ -2914,7 +2913,6 @@
                        /*identity_manager=*/nullptr,
                        /*client_profile_validator=*/nullptr,
                        /*history_service=*/nullptr,
-                       /*cookie_manager_sevice=*/nullptr,
                        /*is_off_the_record=*/false);
   histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", false, 1);
 }
diff --git a/components/autofill/core/browser/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/credit_card_save_manager_unittest.cc
index ef3e151..765d6a3 100644
--- a/components/autofill/core/browser/credit_card_save_manager_unittest.cc
+++ b/components/autofill/core/browser/credit_card_save_manager_unittest.cc
@@ -117,7 +117,6 @@
                         /*identity_manager=*/nullptr,
                         /*client_profile_validator=*/nullptr,
                         /*history_service=*/nullptr,
-                        /*cookie_manager_sevice=*/nullptr,
                         /*is_off_the_record=*/false);
     personal_data_.SetSyncServiceForTest(&sync_service_);
     autocomplete_history_manager_.Init(
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index a205459..00280a55 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -124,7 +124,6 @@
         /*identity_manager=*/nullptr,
         /*client_profile_validator=*/nullptr,
         /*history_service=*/nullptr,
-        /*cookie_manager_sevice=*/nullptr,
         /*is_off_the_record=*/(user_mode == USER_MODE_INCOGNITO));
     personal_data_manager_->AddObserver(&personal_data_observer_);
     personal_data_manager_->OnSyncServiceInitialized(nullptr);
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 2e4ce6e5..472fd8c 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -269,7 +269,6 @@
     identity::IdentityManager* identity_manager,
     AutofillProfileValidator* client_profile_validator,
     history::HistoryService* history_service,
-    GaiaCookieManagerService* cookie_manager_service,
     bool is_off_the_record) {
   CountryNames::SetLocaleString(app_locale_);
   database_helper_->Init(profile_database, account_database);
@@ -288,12 +287,11 @@
   if (history_service_)
     history_service_->AddObserver(this);
 
-  // Listen for cookie deletion by the user.
-  cookie_manager_service_ = cookie_manager_service;
-  if (cookie_manager_service_)
-    cookie_manager_service_->AddObserver(this);
-
+  // Listen for account cookie deletion by the user.
   identity_manager_ = identity_manager;
+  if (identity_manager_)
+    identity_manager_->AddObserver(this);
+
   is_off_the_record_ = is_off_the_record;
 
   if (!is_off_the_record_)
@@ -341,9 +339,9 @@
     history_service_->RemoveObserver(this);
   history_service_ = nullptr;
 
-  if (cookie_manager_service_)
-    cookie_manager_service_->RemoveObserver(this);
-  cookie_manager_service_ = nullptr;
+  if (identity_manager_)
+    identity_manager_->RemoveObserver(this);
+  identity_manager_ = nullptr;
 }
 
 void PersonalDataManager::OnSyncServiceInitialized(
@@ -555,7 +553,7 @@
          !database_helper_->IsUsingAccountStorageForServerData();
 }
 
-void PersonalDataManager::OnGaiaCookieDeletedByUserAction() {
+void PersonalDataManager::OnAccountsCookieDeletedByUserAction() {
   // Clear all the Sync Transport feature opt-ins.
   ::autofill::prefs::ClearSyncTransportOptIns(pref_service_);
 }
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index e5c19e3..69e4b90 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -37,9 +37,9 @@
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_member.h"
 #include "components/signin/core/browser/account_info.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
 #include "components/sync/driver/sync_service_observer.h"
 #include "components/webdata/common/web_data_service_consumer.h"
+#include "services/identity/public/cpp/identity_manager.h"
 
 class Browser;
 class PrefService;
@@ -57,10 +57,6 @@
 void SetCreditCards(int, std::vector<autofill::CreditCard>*);
 }  // namespace autofill_helper
 
-namespace identity {
-class IdentityManager;
-}
-
 namespace syncer {
 class SyncService;
 }  // namespace syncer
@@ -75,7 +71,7 @@
                             public AutofillWebDataServiceObserverOnUISequence,
                             public history::HistoryServiceObserver,
                             public syncer::SyncServiceObserver,
-                            public GaiaCookieManagerService::Observer,
+                            public identity::IdentityManager::Observer,
                             public AccountInfoGetter {
  public:
   explicit PersonalDataManager(const std::string& app_locale);
@@ -96,7 +92,6 @@
             identity::IdentityManager* identity_manager,
             AutofillProfileValidator* client_profile_validator,
             history::HistoryService* history_service,
-            GaiaCookieManagerService* cookie_manager_service,
             bool is_off_the_record);
 
   // KeyedService:
@@ -127,8 +122,8 @@
   CoreAccountInfo GetAccountInfoForPaymentsServer() const override;
   bool IsSyncFeatureEnabled() const override;
 
-  // GaiaCookieManagerService::Observer:
-  void OnGaiaCookieDeletedByUserAction() override;
+  // identity::IdentityManager::Observer:
+  void OnAccountsCookieDeletedByUserAction() override;
 
   // Returns the current sync status.
   AutofillSyncSigninState GetSyncSigninState() const;
@@ -762,11 +757,6 @@
   // remove itself from the history service's observer list on shutdown.
   history::HistoryService* history_service_ = nullptr;
 
-  // The GaiaCookieManagerService to be observed by the personal data manager.
-  // Must outlive this instance. This unowned pointer is retained so the PDM can
-  // remove itself from the cookie manager service's observer list on shutdown.
-  GaiaCookieManagerService* cookie_manager_service_ = nullptr;
-
   // Pref registrar for managing the change observers.
   PrefChangeRegistrar pref_registrar_;
 
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index e9f57feb..9955875 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -187,10 +187,10 @@
 
   void ResetPersonalDataManager(UserMode user_mode,
                                 bool use_sync_transport_mode,
-                                PersonalDataManager* personal_data_) {
+                                PersonalDataManager* personal_data) {
     bool is_incognito = (user_mode == USER_MODE_INCOGNITO);
 
-    personal_data_->Init(
+    personal_data->Init(
         scoped_refptr<AutofillWebDataService>(profile_database_service_),
         base::FeatureList::IsEnabled(
             features::kAutofillEnableAccountWalletStorage)
@@ -198,28 +198,27 @@
             : nullptr,
         prefs_.get(), identity_test_env_.identity_manager(),
         TestAutofillProfileValidator::GetInstance(),
-        /*history_service=*/nullptr, /*cookie_manager_sevice=*/nullptr,
-        is_incognito);
+        /*history_service=*/nullptr, is_incognito);
 
-    personal_data_->AddObserver(&personal_data_observer_);
+    personal_data->AddObserver(&personal_data_observer_);
     AccountInfo account_info;
     account_info.email = "sync@account";
     sync_service_.SetAuthenticatedAccountInfo(account_info);
     sync_service_.SetIsAuthenticatedAccountPrimary(!use_sync_transport_mode);
-    personal_data_->OnSyncServiceInitialized(&sync_service_);
-    personal_data_->OnStateChanged(&sync_service_);
+    personal_data->OnSyncServiceInitialized(&sync_service_);
+    personal_data->OnStateChanged(&sync_service_);
 
     WaitForOnPersonalDataChangedRepeatedly();
   }
 
-  bool TurnOnSyncFeature(PersonalDataManager* personal_data_)
+  bool TurnOnSyncFeature(PersonalDataManager* personal_data)
       WARN_UNUSED_RESULT {
     sync_service_.SetIsAuthenticatedAccountPrimary(true);
     if (!sync_service_.IsSyncFeatureEnabled())
       return false;
-    personal_data_->OnStateChanged(&sync_service_);
+    personal_data->OnStateChanged(&sync_service_);
 
-    return personal_data_->IsSyncFeatureEnabled();
+    return personal_data->IsSyncFeatureEnabled();
   }
 
   void EnableWalletCardImport() {
@@ -228,16 +227,15 @@
         switches::kEnableOfferStoreUnmaskedWalletCards);
   }
 
-  void RemoveByGUIDFromPersonalDataManager(
-      const std::string& guid,
-      PersonalDataManager* personal_data_) {
+  void RemoveByGUIDFromPersonalDataManager(const std::string& guid,
+                                           PersonalDataManager* personal_data) {
     base::RunLoop run_loop;
     EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
         .WillOnce(QuitMessageLoop(&run_loop));
     EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
         .Times(testing::AnyNumber());
 
-    personal_data_->RemoveByGUID(guid);
+    personal_data->RemoveByGUID(guid);
     run_loop.Run();
   }
 
@@ -283,14 +281,14 @@
     return account_info;
   }
 
-  void MoveJapanCityToStreetAddress(PersonalDataManager* personal_data_,
+  void MoveJapanCityToStreetAddress(PersonalDataManager* personal_data,
                                     int move_times) {
     base::RunLoop run_loop;
     EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
         .WillRepeatedly(QuitMessageLoop(&run_loop));
     EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
         .Times(move_times);
-    personal_data_->MoveJapanCityToStreetAddress();
+    personal_data->MoveJapanCityToStreetAddress();
     run_loop.Run();
   }
 
@@ -314,8 +312,16 @@
 
 class PersonalDataManagerHelper : public PersonalDataManagerTestBase {
  protected:
+  virtual ~PersonalDataManagerHelper() {
+    if (personal_data_)
+      personal_data_->Shutdown();
+    personal_data_.reset();
+  }
+
   void ResetPersonalDataManager(UserMode user_mode,
                                 bool use_account_server_storage = false) {
+    if (personal_data_)
+      personal_data_->Shutdown();
     personal_data_.reset(new PersonalDataManager("en"));
     PersonalDataManagerTestBase::ResetPersonalDataManager(
         user_mode, use_account_server_storage, personal_data_.get());
@@ -556,9 +562,17 @@
         atoi(version_info::GetVersionNumber().c_str()));
     personal_data_->is_autofill_profile_cleanup_pending_ = true;
   }
-  void TearDown() override { TearDownTest(); }
+
+  void TearDown() override {
+    if (personal_data_)
+      personal_data_->Shutdown();
+    personal_data_.reset();
+    TearDownTest();
+  }
 
   void ResetPersonalDataManager(UserMode user_mode) {
+    if (personal_data_)
+      personal_data_->Shutdown();
     personal_data_.reset(new PersonalDataManagerMock("en"));
     PersonalDataManagerTestBase::ResetPersonalDataManager(
         user_mode, /*use_account_server_storage=*/true, personal_data_.get());
@@ -6432,6 +6446,10 @@
       1);
   histogram_tester.ExpectUniqueSample(
       "Autofill.ResetFullServerCards.NumberOfCardsReset", 1, 1);
+
+  // Call OnSyncShutdown to ensure removing observer added by
+  // OnSyncServiceInitialized.
+  personal_data_->OnSyncShutdown(&sync_service);
 }
 #endif  // !defined(OS_LINUX) || defined(OS_CHROMEOS)
 
@@ -7365,7 +7383,7 @@
   }
 }
 
-TEST_F(PersonalDataManagerTest, OnGaiaCookieDeletedByUserAction) {
+TEST_F(PersonalDataManagerTest, OnAccountsCookieDeletedByUserAction) {
   // Set up some sync transport opt-ins in the prefs.
   ::autofill::prefs::SetUserOptedInWalletSyncTransport(prefs_.get(), "account1",
                                                        true);
@@ -7373,7 +7391,7 @@
       prefs_->GetDictionary(prefs::kAutofillSyncTransportOptIn)->DictEmpty());
 
   // Simulate that the cookies get cleared by the user.
-  personal_data_->OnGaiaCookieDeletedByUserAction();
+  personal_data_->OnAccountsCookieDeletedByUserAction();
 
   // Make sure the pref is now empty.
   EXPECT_TRUE(
diff --git a/components/autofill_assistant/browser/actions/action.cc b/components/autofill_assistant/browser/actions/action.cc
index d90f037..9b1c55f 100644
--- a/components/autofill_assistant/browser/actions/action.cc
+++ b/components/autofill_assistant/browser/actions/action.cc
@@ -36,4 +36,80 @@
   return vector;
 }
 
+std::ostream& operator<<(std::ostream& out, const Action& action) {
+  out << action.proto().action_info_case();
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out,
+                         const ActionProto::ActionInfoCase& action_case) {
+#ifdef NDEBUG
+  out << static_cast<int>(action_case);
+  return out;
+#else
+  switch (action_case) {
+    case ActionProto::ActionInfoCase::kClick:
+      out << "Click";
+      break;
+    case ActionProto::ActionInfoCase::kSetFormValue:
+      out << "KeyboardInput";
+      break;
+    case ActionProto::ActionInfoCase::kSelectOption:
+      out << "SelectOption";
+      break;
+    case ActionProto::ActionInfoCase::kNavigate:
+      out << "Navigate";
+      break;
+    case ActionProto::ActionInfoCase::kPrompt:
+      out << "Prompt";
+      break;
+    case ActionProto::ActionInfoCase::kTell:
+      out << "Tell";
+      break;
+    case ActionProto::ActionInfoCase::kFocusElement:
+      out << "FocusElement";
+      break;
+    case ActionProto::ActionInfoCase::kWaitForDom:
+      out << "WaitForDom";
+      break;
+    case ActionProto::ActionInfoCase::kUseCard:
+      out << "UseCard";
+      break;
+    case ActionProto::ActionInfoCase::kUseAddress:
+      out << "UseAddress";
+      break;
+    case ActionProto::ActionInfoCase::kUploadDom:
+      out << "UploadDom";
+      break;
+    case ActionProto::ActionInfoCase::kShowProgressBar:
+      out << "ShowProgressBar";
+      break;
+    case ActionProto::ActionInfoCase::kHighlightElement:
+      out << "HighlightElement";
+      break;
+    case ActionProto::ActionInfoCase::kShowDetails:
+      out << "ShowDetails";
+      break;
+    case ActionProto::ActionInfoCase::kReset:
+      out << "Reset";
+      break;
+    case ActionProto::ActionInfoCase::kStop:
+      out << "Stop";
+      break;
+    case ActionProto::ActionInfoCase::kGetPaymentInformation:
+      out << "GetPaymentInformation";
+      break;
+    case ActionProto::ActionInfoCase::kSetAttribute:
+      out << "SetAttribute";
+      break;
+    case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET:
+      out << "ACTION_INFO_NOT_SET";
+      break;
+      // Intentionally no default case to make compilation fail if a new value
+      // was added to the enum but not to this list.
+  }
+  return out;
+#endif  // NDEBUG
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/action.h b/components/autofill_assistant/browser/actions/action.h
index 0ecf297..fda288a 100644
--- a/components/autofill_assistant/browser/actions/action.h
+++ b/components/autofill_assistant/browser/actions/action.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_ACTION_H_
 
 #include <memory>
+#include <ostream>
 #include <string>
 #include <vector>
 
@@ -45,6 +46,10 @@
 
   void UpdateProcessedAction(ProcessedActionStatusProto status);
 
+  // Intended for debugging. Writes a string representation of |action| to
+  // |out|.
+  friend std::ostream& operator<<(std::ostream& out, const Action& action);
+
   const ActionProto proto_;
 
   // Accumulate any result of this action during ProcessAction. Is only valid
@@ -52,5 +57,10 @@
   std::unique_ptr<ProcessedActionProto> processed_action_proto_;
 };
 
+// Intended for debugging. Writes a string representation of |action_case| to
+// |out|.
+std::ostream& operator<<(std::ostream& out,
+                         const ActionProto::ActionInfoCase& action_case);
+
 }  // namespace autofill_assistant
 #endif  // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_ACTION_H_
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc
index 88cc8c5..ba3964d 100644
--- a/components/autofill_assistant/browser/controller.cc
+++ b/components/autofill_assistant/browser/controller.cc
@@ -217,6 +217,7 @@
   if (script_domain_ != url.host()) {
     StopPeriodicScriptChecks();
     script_domain_ = url.host();
+    DVLOG(2) << "GetScripts for " << script_domain_;
     GetService()->GetScriptsForUrl(
         url, parameters_,
         base::BindOnce(&Controller::OnGetScripts, base::Unretained(this), url));
@@ -287,6 +288,8 @@
 
   std::vector<std::unique_ptr<Script>> scripts;
   bool parse_result = ProtocolUtils::ParseScripts(response, &scripts);
+  DVLOG(2) << __func__ << " from " << url.host() << " returned "
+           << scripts.size() << " scripts";
   DCHECK(parse_result);
   script_tracker()->SetScripts(std::move(scripts));
   script_tracker()->CheckScripts(kPeriodicScriptCheckInterval);
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc
index e1de1c8..80a0f09 100644
--- a/components/autofill_assistant/browser/script_executor.cc
+++ b/components/autofill_assistant/browser/script_executor.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill_assistant/browser/script_executor.h"
 
+#include <ostream>
 #include <string>
 #include <utility>
 
@@ -14,6 +15,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill_assistant/browser/actions/action.h"
 #include "components/autofill_assistant/browser/batch_element_checker.h"
 #include "components/autofill_assistant/browser/client_memory.h"
 #include "components/autofill_assistant/browser/protocol_utils.h"
@@ -31,6 +33,82 @@
 // to show up.
 constexpr base::TimeDelta kShortWaitForElementDeadline =
     base::TimeDelta::FromSeconds(2);
+
+// Intended for debugging. Writes a string representation of the status to
+// |out|.
+std::ostream& operator<<(std::ostream& out,
+                         const ProcessedActionStatusProto& status) {
+#ifdef NDEBUG
+  out << static_cast<int>(status);
+  return out;
+#else
+  switch (status) {
+    case ProcessedActionStatusProto::UNKNOWN_ACTION_STATUS:
+      out << "UNKNOWN_ACTION_STATUS";
+      break;
+    case ProcessedActionStatusProto::ELEMENT_RESOLUTION_FAILED:
+      out << "ELEMENT_RESOLUTION_FAILED";
+      break;
+    case ProcessedActionStatusProto::ACTION_APPLIED:
+      out << "ACTION_APPLIED";
+      break;
+    case ProcessedActionStatusProto::OTHER_ACTION_STATUS:
+      out << "OTHER_ACTION_STATUS";
+      break;
+    case ProcessedActionStatusProto::PAYMENT_REQUEST_ERROR:
+      out << "PAYMENT_REQUEST_ERROR";
+      break;
+    case ProcessedActionStatusProto::UNSUPPORTED_ACTION:
+      out << "UNSUPPORTED_ACTION";
+      break;
+    case ProcessedActionStatusProto::MANUAL_FALLBACK:
+      out << "MANUAL_FALLBACK";
+      break;
+    case ProcessedActionStatusProto::INTERRUPT_FAILED:
+      out << "INTERRUPT_FAILED";
+      break;
+    case ProcessedActionStatusProto::USER_ABORTED_ACTION:
+      out << "USER_ABORTED_ACTION";
+      break;
+      // Intentionally no default case to make compilation fail if a new value
+      // was added to the enum but not to this list.
+  }
+  return out;
+#endif  // NDEBUG
+}
+
+std::ostream& operator<<(std::ostream& out,
+                         const ScriptExecutor::AtEnd& at_end) {
+#ifdef NDEBUG
+  out << static_cast<int>(at_end);
+  return out;
+#else
+  switch (at_end) {
+    case ScriptExecutor::CONTINUE:
+      out << "CONTINUE";
+      break;
+    case ScriptExecutor::SHUTDOWN:
+      out << "SHUTDOWN";
+      break;
+    case ScriptExecutor::SHUTDOWN_GRACEFULLY:
+      out << "SHUTDOWN_GRACEFULLY";
+      break;
+    case ScriptExecutor::CLOSE_CUSTOM_TAB:
+      out << "CLOSE_CUSTOM_TAB";
+      break;
+    case ScriptExecutor::RESTART:
+      out << "RESTART";
+      break;
+    case ScriptExecutor::TERMINATE:
+      out << "TERMINATE";
+      break;
+      // Intentionally no default case to make compilation fail if a new value
+      // was added to the enum but not to this list.
+  }
+  return out;
+#endif  // NDEBUG
+}
+
 }  // namespace
 
 ScriptExecutor::ScriptExecutor(
@@ -63,11 +141,14 @@
 ScriptExecutor::Result::~Result() = default;
 
 void ScriptExecutor::Run(RunScriptCallback callback) {
+  DVLOG(2) << "Starting script " << script_path_;
   (*scripts_state_)[script_path_] = SCRIPT_STATUS_RUNNING;
 
   callback_ = std::move(callback);
   DCHECK(delegate_->GetService());
 
+  DVLOG(2) << "GetActions for "
+           << delegate_->GetWebController()->GetUrl().host();
   delegate_->GetService()->GetActions(
       script_path_, delegate_->GetWebController()->GetUrl(),
       delegate_->GetParameters(), last_global_payload_, last_script_payload_,
@@ -339,6 +420,7 @@
 
 void ScriptExecutor::OnGetActions(bool result, const std::string& response) {
   bool success = result && ProcessNextActionResponse(response);
+  DVLOG(2) << __func__ << " result=" << result;
   if (should_stop_script_) {
     // The last action forced the script to stop. Sending the result of the
     // action is considered best effort in this situation. Report a successful
@@ -423,7 +505,7 @@
   // we could have more |processed_actions| than |actions_|.
   if (actions_.size() <= processed_actions_.size()) {
     DCHECK_EQ(actions_.size(), processed_actions_.size());
-    // Request more actions to execute.
+    DVLOG(2) << __func__ << ", get more actions";
     GetNextActions();
     return;
   }
@@ -443,6 +525,7 @@
 }
 
 void ScriptExecutor::ProcessAction(Action* action) {
+  DVLOG(2) << "Begin action: " << *action;
   action->ProcessAction(this, base::BindOnce(&ScriptExecutor::OnProcessedAction,
                                              weak_ptr_factory_.GetWeakPtr()));
 }
@@ -467,6 +550,8 @@
         ProcessedActionStatusProto::USER_ABORTED_ACTION);
   }
   if (processed_action.status() != ProcessedActionStatusProto::ACTION_APPLIED) {
+    DVLOG(1) << "Action failed: " << processed_action.status()
+             << ", get more actions";
     // Report error immediately, interrupting action processing.
     GetNextActions();
     return;
@@ -698,4 +783,11 @@
     interrupt_executor_->Terminate();
 }
 
+std::ostream& operator<<(std::ostream& out,
+                         const ScriptExecutor::Result& result) {
+  result.success ? out << "succeeded. " : out << "failed. ";
+  out << "at_end = " << result.at_end;
+  return out;
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h
index 18fdcadd..9fea1a11 100644
--- a/components/autofill_assistant/browser/script_executor.h
+++ b/components/autofill_assistant/browser/script_executor.h
@@ -8,6 +8,7 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <ostream>
 #include <set>
 #include <string>
 #include <vector>
@@ -87,6 +88,8 @@
 
     Result();
     ~Result();
+
+    friend std::ostream& operator<<(std::ostream& out, const Result& result);
   };
 
   using RunScriptCallback = base::OnceCallback<void(const Result&)>;
diff --git a/components/browser_sync/profile_sync_service_autofill_unittest.cc b/components/browser_sync/profile_sync_service_autofill_unittest.cc
index fcff9d7..84f22c1 100644
--- a/components/browser_sync/profile_sync_service_autofill_unittest.cc
+++ b/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -396,7 +396,6 @@
                                  /*identity_manager=*/nullptr,
                                  /*client_profile_validator=*/nullptr,
                                  /*history_service=*/nullptr,
-                                 /*cookie_manager_sevice=*/nullptr,
                                  /*is_off_the_record=*/false);
 
     web_data_service_->StartSyncableService();
diff --git a/components/component_updater/configurator_impl.cc b/components/component_updater/configurator_impl.cc
index 2a964f7..86f70034 100644
--- a/components/component_updater/configurator_impl.cc
+++ b/components/component_updater/configurator_impl.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 
+#include "base/callback.h"
 #include "base/feature_list.h"
 #include "base/stl_util.h"
 #include "base/strings/string_split.h"
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc
index f910e2ce4..5ac6cb4 100644
--- a/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc
+++ b/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc
@@ -184,11 +184,8 @@
 
 ContextualSuggestionsFetch::ContextualSuggestionsFetch(
     const GURL& url,
-    const std::string& bcp_language_code,
-    bool include_cookies)
-    : url_(url),
-      bcp_language_code_(bcp_language_code),
-      include_cookies_(include_cookies) {}
+    const std::string& bcp_language_code)
+    : url_(url), bcp_language_code_(bcp_language_code) {}
 
 ContextualSuggestionsFetch::~ContextualSuggestionsFetch() = default;
 
@@ -273,11 +270,8 @@
   resource_request->url = GURL(GetFetchEndpoint());
   resource_request->method = "GET";
   AppendHeaders(resource_request.get());
-
-  int cookie_flag = include_cookies_ ? 0 : net::LOAD_DO_NOT_SEND_COOKIES;
-  resource_request->load_flags = net::LOAD_BYPASS_CACHE |
-                                 net::LOAD_DO_NOT_SAVE_COOKIES | cookie_flag |
-                                 net::LOAD_DO_NOT_SEND_AUTH_DATA;
+  resource_request->load_flags = net::LOAD_BYPASS_CACHE;
+  resource_request->allow_credentials = false;
 
   return resource_request;
 }
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetch.h b/components/ntp_snippets/contextual/contextual_suggestions_fetch.h
index dd8845f..15f371a4e0 100644
--- a/components/ntp_snippets/contextual/contextual_suggestions_fetch.h
+++ b/components/ntp_snippets/contextual/contextual_suggestions_fetch.h
@@ -28,9 +28,7 @@
 // body protos and parsing the response body protos.
 class ContextualSuggestionsFetch {
  public:
-  ContextualSuggestionsFetch(const GURL& url,
-                             const std::string& bcp_language,
-                             bool include_cookies);
+  ContextualSuggestionsFetch(const GURL& url, const std::string& bcp_language);
   ~ContextualSuggestionsFetch();
 
   // Get the url used to fetch suggestions.
@@ -62,8 +60,6 @@
   // Identifier for the spoken language in BCP47 format.
   const std::string bcp_language_code_;
 
-  bool include_cookies_ = false;
-
   // The loader for downloading the suggestions. Only non-null if a fetch is
   // currently ongoing.
   std::unique_ptr<network::SimpleURLLoader> url_loader_;
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc
index 337d1f3..ee17787 100644
--- a/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc
+++ b/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc
@@ -95,7 +95,7 @@
             variations::VariationsHttpHeaderProvider::GetInstance()
                 ->ForceVariationIds({"12345"}, ""));
 
-  ContextualSuggestionsFetch fetch(GURL("http://test.com"), "en-US", false);
+  ContextualSuggestionsFetch fetch(GURL("http://test.com"), "en-US");
   std::unique_ptr<network::ResourceRequest> resource_request =
       fetch.MakeResourceRequestForTesting();
 
@@ -115,7 +115,7 @@
             variations::VariationsHttpHeaderProvider::GetInstance()
                 ->ForceVariationIds({"12345"}, ""));
 
-  ContextualSuggestionsFetch fetch(GURL("http://test.com"), "en-US", false);
+  ContextualSuggestionsFetch fetch(GURL("http://test.com"), "en-US");
   std::unique_ptr<network::ResourceRequest> resource_request =
       fetch.MakeResourceRequestForTesting();
 
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc
index b5a334c..be21e89 100644
--- a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc
+++ b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc
@@ -13,11 +13,8 @@
 
 ContextualSuggestionsFetcherImpl::ContextualSuggestionsFetcherImpl(
     const scoped_refptr<network::SharedURLLoaderFactory>& loader_factory,
-    std::unique_ptr<unified_consent::UrlKeyedDataCollectionConsentHelper>
-        consent_helper,
     const std::string& application_language_code)
     : loader_factory_(loader_factory),
-      consent_helper_(std::move(consent_helper)),
       bcp_language_code_(application_language_code) {}
 
 ContextualSuggestionsFetcherImpl::~ContextualSuggestionsFetcherImpl() = default;
@@ -26,9 +23,8 @@
     const GURL& url,
     FetchClustersCallback callback,
     ReportFetchMetricsCallback metrics_callback) {
-  bool include_cookies = consent_helper_ && consent_helper_->IsEnabled();
-  auto fetch = std::make_unique<ContextualSuggestionsFetch>(
-      url, bcp_language_code_, include_cookies);
+  auto fetch =
+      std::make_unique<ContextualSuggestionsFetch>(url, bcp_language_code_);
   ContextualSuggestionsFetch* fetch_unowned = fetch.get();
   pending_requests_.emplace(std::move(fetch));
 
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h
index 65410f84..3eccc9d 100644
--- a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h
+++ b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h
@@ -15,7 +15,6 @@
 #include "components/ntp_snippets/contextual/contextual_suggestion.h"
 #include "components/ntp_snippets/contextual/contextual_suggestions_fetch.h"
 #include "components/ntp_snippets/contextual/contextual_suggestions_fetcher.h"
-#include "components/unified_consent/url_keyed_data_collection_consent_helper.h"
 
 namespace network {
 class SharedURLLoaderFactory;
@@ -31,8 +30,6 @@
  public:
   ContextualSuggestionsFetcherImpl(
       const scoped_refptr<network::SharedURLLoaderFactory>& loader_factory,
-      std::unique_ptr<unified_consent::UrlKeyedDataCollectionConsentHelper>
-          consent_helper,
       const std::string& application_language_code);
   ~ContextualSuggestionsFetcherImpl() override;
 
@@ -48,8 +45,6 @@
                      ContextualSuggestionsResult result);
 
   const scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
-  std::unique_ptr<unified_consent::UrlKeyedDataCollectionConsentHelper>
-      consent_helper_;
   /// BCP47 formatted language code to use.
   const std::string bcp_language_code_;
 
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
index cd7b469..8d4b9411 100644
--- a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
+++ b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
@@ -148,36 +148,18 @@
 
 }  // namespace
 
-class TestUrlKeyedDataCollectionConsentHelper
-    : public unified_consent::UrlKeyedDataCollectionConsentHelper {
- public:
-  TestUrlKeyedDataCollectionConsentHelper() = default;
-  ~TestUrlKeyedDataCollectionConsentHelper() override = default;
-
-  bool IsEnabled() override { return is_enabled_; }
-  void SetIsEnabled(bool enabled) { is_enabled_ = enabled; }
-
- private:
-  bool is_enabled_ = false;
-};
-
 class ContextualSuggestionsFetcherTest : public testing::Test {
  public:
   ContextualSuggestionsFetcherTest() {
     shared_url_loader_factory_ =
         base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
             &test_factory_);
-    auto consent_helper =
-        std::make_unique<TestUrlKeyedDataCollectionConsentHelper>();
-    consent_helper_ = consent_helper.get();
     fetcher_ = std::make_unique<ContextualSuggestionsFetcherImpl>(
-        shared_url_loader_factory_, std::move(consent_helper), "en");
+        shared_url_loader_factory_, "en");
   }
 
   ~ContextualSuggestionsFetcherTest() override {}
 
-  void SetUp() override { consent_helper()->SetIsEnabled(true); }
-
   void SetFakeResponse(const std::string& response_data,
                        net::HttpStatusCode response_code = net::HTTP_OK,
                        network::URLLoaderCompletionStatus status =
@@ -211,15 +193,10 @@
 
   TestURLLoaderFactory* test_factory() { return &test_factory_; }
 
-  TestUrlKeyedDataCollectionConsentHelper* consent_helper() {
-    return consent_helper_;
-  }
-
  private:
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   network::TestURLLoaderFactory test_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
-  TestUrlKeyedDataCollectionConsentHelper* consent_helper_;
   std::unique_ptr<ContextualSuggestionsFetcherImpl> fetcher_;
 
   DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsFetcherTest);
@@ -436,7 +413,7 @@
       "ContextualSuggestions.FetchRequestProtoSizeKB", 1);
 }
 
-TEST_F(ContextualSuggestionsFetcherTest, CookiesIncludedWhenConsentIsEnabled) {
+TEST_F(ContextualSuggestionsFetcherTest, CredentialsExcluded) {
   network::ResourceRequest last_resource_request;
 
   test_factory()->SetInterceptor(
@@ -448,28 +425,7 @@
 
   MockClustersCallback callback;
   SendAndAwaitResponse(GURL("http://www.article.com/"), &callback);
-
-  int load_flags = last_resource_request.load_flags;
-  EXPECT_EQ(0, load_flags & net::LOAD_DO_NOT_SEND_COOKIES);
-}
-
-TEST_F(ContextualSuggestionsFetcherTest, CookiesExcludedWhenConsentIsDisabled) {
-  consent_helper()->SetIsEnabled(false);
-  network::ResourceRequest last_resource_request;
-
-  test_factory()->SetInterceptor(
-      base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
-        last_resource_request = request;
-      }));
-
-  SetFakeResponse(SerializedResponseProto("Peek Text", DefaultClusters()));
-
-  MockClustersCallback callback;
-  SendAndAwaitResponse(GURL("http://www.article.com/"), &callback);
-
-  int load_flags = last_resource_request.load_flags;
-  EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES,
-            load_flags & net::LOAD_DO_NOT_SEND_COOKIES);
+  EXPECT_FALSE(last_resource_request.allow_credentials);
 }
 
 TEST_F(ContextualSuggestionsFetcherTest, ProtocolError) {
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index 6f03e13..428d0c7 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -1248,7 +1248,7 @@
     // temporary text back to a default match that's a keyword search, but in
     // that case the RevertTemporaryText() call below will reset the caret or
     // selection correctly so the caret positioning we do here won't matter.
-    view_->SetWindowTextAndCaretPos(user_text, 0, false, false);
+    view_->SetWindowTextAndCaretPos(user_text, 0, false, true);
   } else if (view_->OnInlineAutocompleteTextMaybeChanged(
                  user_text + inline_autocomplete_text_, user_text.length())) {
     call_controller_onchanged = false;
diff --git a/components/omnibox/browser/omnibox_popup_model.cc b/components/omnibox/browser/omnibox_popup_model.cc
index 7f15800..eff91c23 100644
--- a/components/omnibox/browser/omnibox_popup_model.cc
+++ b/components/omnibox/browser/omnibox_popup_model.cc
@@ -160,10 +160,6 @@
     edit_model_->OnPopupDataChanged(match.fill_into_edit, &current_destination,
                                     keyword, is_keyword_hint);
   }
-
-  // Repaint old and new selected lines immediately, so that the edit doesn't
-  // appear to update [much] faster than the popup.
-  view_->PaintUpdatesNow();
 }
 
 void OmniboxPopupModel::ResetToDefaultMatch() {
diff --git a/components/omnibox/browser/omnibox_popup_model_unittest.cc b/components/omnibox/browser/omnibox_popup_model_unittest.cc
index ac1a0c8..a75cf2e 100644
--- a/components/omnibox/browser/omnibox_popup_model_unittest.cc
+++ b/components/omnibox/browser/omnibox_popup_model_unittest.cc
@@ -32,7 +32,6 @@
   void OnLineSelected(size_t line) override {}
   void UpdatePopupAppearance() override {}
   void OnMatchIconUpdated(size_t match_index) override {}
-  void PaintUpdatesNow() override {}
   void OnDragCanceled() override {}
 };
 
diff --git a/components/omnibox/browser/omnibox_popup_view.h b/components/omnibox/browser/omnibox_popup_view.h
index 5b19519..c2cfb4a 100644
--- a/components/omnibox/browser/omnibox_popup_view.h
+++ b/components/omnibox/browser/omnibox_popup_view.h
@@ -35,9 +35,6 @@
   // Notification that the icon used for the given match has been updated.
   virtual void OnMatchIconUpdated(size_t match_index) = 0;
 
-  // Paint any pending updates.
-  virtual void PaintUpdatesNow() = 0;
-
   // This method is called when the view should cancel any active drag (e.g.
   // because the user pressed ESC). The view may or may not need to take any
   // action (e.g. releasing mouse capture).  Note that this can be called when
diff --git a/components/signin/core/browser/account_investigator_unittest.cc b/components/signin/core/browser/account_investigator_unittest.cc
index e64045d..15c5d5c 100644
--- a/components/signin/core/browser/account_investigator_unittest.cc
+++ b/components/signin/core/browser/account_investigator_unittest.cc
@@ -360,7 +360,7 @@
 }
 
 TEST_F(AccountInvestigatorTest, TryPeriodicReportEmpty) {
-  identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
+  identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(true);
   const HistogramTester histogram_tester;
 
   TryPeriodicReport();
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc
index 6f68ef1..084af7ad 100644
--- a/components/signin/core/browser/account_reconcilor_unittest.cc
+++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -668,7 +668,7 @@
     }
     signin::SetListAccountsResponseWithParams(cookie_params,
                                               &test_url_loader_factory_);
-    identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(true);
+    identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
   }
 
   std::string GaiaIdForAccountKey(char account_key) {
@@ -1329,7 +1329,7 @@
 
   // Delete the cookies.
   signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
-  identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(true);
+  identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
 
   if (!IsMultiloginEnabled()) {
     // Reconcile again and check that account_id_2 is added first.
@@ -2437,7 +2437,7 @@
   signin::SetListAccountsResponseTwoAccounts(
       account_info.email, account_info.gaia, account_info2.email,
       account_info2.gaia, &test_url_loader_factory_);
-  identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(true);
+  identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
 
   // This will cause the reconcilor to fire.
   identity_test_env()->SetRefreshTokenForAccount(account_id3);
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc
index db114d2..c54433c 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.cc
+++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -16,8 +16,10 @@
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "components/data_use_measurement/core/data_use_user_data.h"
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/signin_metrics.h"
@@ -688,6 +690,16 @@
   return shared_url_loader_factory_getter_.Run();
 }
 
+void GaiaCookieManagerService::MarkListAccountsStale() {
+  list_accounts_stale_ = true;
+#if defined(OS_IOS)
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&GaiaCookieManagerService::ForceOnCookieChangeProcessing,
+                     weak_ptr_factory_.GetWeakPtr()));
+#endif  // defined(OS_IOS)
+}
+
 void GaiaCookieManagerService::OnCookieChange(
     const net::CanonicalCookie& cookie,
     network::mojom::CookieChangeCause cause) {
@@ -824,8 +836,7 @@
   DCHECK(requests_.front().request_type() ==
          GaiaCookieRequestType::ADD_ACCOUNT);
 
-  list_accounts_stale_ = true;
-
+  MarkListAccountsStale();
   HandleNextRequest();
   SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone());
 
@@ -983,7 +994,7 @@
   VLOG(1) << "GaiaCookieManagerService::OnLogOutSuccess";
   RecordLogoutRequestState(LogoutRequestState::kSuccess);
 
-  list_accounts_stale_ = true;
+  MarkListAccountsStale();
   fetcher_backoff_.InformOfRequest(true);
   for (auto& observer : observer_list_) {
     observer.OnLogOutAccountsFromCookieCompleted(
@@ -1091,9 +1102,7 @@
 
 void GaiaCookieManagerService::OnSetAccountsFinished(
     const GoogleServiceAuthError& error) {
-  // Set ListAccounts result to stale manually because on iOS
-  // GaiaCookieManagerService is not notified about changes in cookie storage.
-  list_accounts_stale_ = true;
+  MarkListAccountsStale();
   access_tokens_.clear();
   token_requests_.clear();
   cookies_to_set_.clear();
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.h b/components/signin/core/browser/gaia_cookie_manager_service.h
index 7c8a107..cb6129ba 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.h
+++ b/components/signin/core/browser/gaia_cookie_manager_service.h
@@ -337,6 +337,10 @@
 
   scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory();
 
+  // Marks the list account being staled, and for iOS only, it triggers to fetch
+  // the list of accounts (on iOS there is no OnCookieChange() notification).
+  void MarkListAccountsStale();
+
   // Overridden from network::mojom::CookieChangeListner. If the cookie relates
   // to a GAIA APISID cookie, then we call ListAccounts and fire
   // OnGaiaAccountsInCookieUpdated.
diff --git a/components/signin/core/browser/signin_manager.h b/components/signin/core/browser/signin_manager.h
index 4582c5c..0141fef 100644
--- a/components/signin/core/browser/signin_manager.h
+++ b/components/signin/core/browser/signin_manager.h
@@ -6,11 +6,6 @@
 // which user is signed in. See SigninManagerBase for full description of
 // responsibilities. The class defined in this file provides functionality
 // required by all platforms except Chrome OS.
-//
-// When a user is signed in, a ClientLogin request is run on their behalf.
-// Auth tokens are fetched from Google and the results are stored in the
-// TokenService.
-// TODO(tim): Bug 92948, 226464. ClientLogin is all but gone from use.
 
 #ifndef COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_MANAGER_H_
 #define COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_MANAGER_H_
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h
index ff60c495..5a80e91 100644
--- a/components/signin/core/browser/signin_manager_base.h
+++ b/components/signin/core/browser/signin_manager_base.h
@@ -136,11 +136,6 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
-  // Gives access to the SigninClient instance associated with this instance.
-  SigninClient* signin_client() const { return client_; }
-
-  ProfileOAuth2TokenService* token_service() const { return token_service_; }
-
   // Adds a callback that will be called when this instance is shut down.Not
   // intended for general usage, but rather for usage only by the Identity
   // Service implementation during the time period of conversion of Chrome to
@@ -151,6 +146,10 @@
   }
 
  protected:
+  SigninClient* signin_client() const { return client_; }
+
+  ProfileOAuth2TokenService* token_service() const { return token_service_; }
+
   AccountTrackerService* account_tracker_service() const {
     return account_tracker_service_;
   }
diff --git a/components/sync/driver/backend_migrator_unittest.cc b/components/sync/driver/backend_migrator_unittest.cc
index be8eb4b..21f059f 100644
--- a/components/sync/driver/backend_migrator_unittest.cc
+++ b/components/sync/driver/backend_migrator_unittest.cc
@@ -287,4 +287,4 @@
   EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
 }
 
-};  // namespace syncer
+}  // namespace syncer
diff --git a/components/sync/driver/glue/sync_backend_host_core.cc b/components/sync/driver/glue/sync_backend_host_core.cc
index ee27878..d3ca947 100644
--- a/components/sync/driver/glue/sync_backend_host_core.cc
+++ b/components/sync/driver/glue/sync_backend_host_core.cc
@@ -18,6 +18,7 @@
 #include "components/invalidation/public/object_id_invalidation_map.h"
 #include "components/sync/base/get_session_name.h"
 #include "components/sync/base/invalidation_adapter.h"
+#include "components/sync/base/sync_base_switches.h"
 #include "components/sync/device_info/local_device_info_provider_impl.h"
 #include "components/sync/engine/cycle/commit_counters.h"
 #include "components/sync/engine/cycle/status_counters.h"
@@ -620,6 +621,11 @@
 
 void SyncBackendHostCore::DoOnInvalidatorClientIdChange(
     const std::string& client_id) {
+  if (base::FeatureList::IsEnabled(switches::kSyncE2ELatencyMeasurement)) {
+    // Don't populate the ID, if client participates in latency measurement
+    // experiment.
+    return;
+  }
   sync_manager_->UpdateInvalidationClientId(client_id);
 }
 
diff --git a/components/sync/model/mock_model_type_change_processor.cc b/components/sync/model/mock_model_type_change_processor.cc
index 398c4de..415429e3 100644
--- a/components/sync/model/mock_model_type_change_processor.cc
+++ b/components/sync/model/mock_model_type_change_processor.cc
@@ -21,7 +21,7 @@
   // |other| must not be nullptr and must outlive this object.
   explicit ForwardingModelTypeChangeProcessor(ModelTypeChangeProcessor* other)
       : other_(other) {}
-  ~ForwardingModelTypeChangeProcessor() override{};
+  ~ForwardingModelTypeChangeProcessor() override {}
 
   void Put(const std::string& client_tag,
            std::unique_ptr<EntityData> entity_data,
diff --git a/components/sync_sessions/lost_navigations_recorder_unittest.cc b/components/sync_sessions/lost_navigations_recorder_unittest.cc
index 495e6a0..f3efa70 100644
--- a/components/sync_sessions/lost_navigations_recorder_unittest.cc
+++ b/components/sync_sessions/lost_navigations_recorder_unittest.cc
@@ -392,5 +392,5 @@
   histogram_tester.ExpectBucketCount("Sync.LostNavigationCount", 2, 1);
 }
 
-};  // namespace
-};  // namespace sync_sessions
+}  // namespace
+}  // namespace sync_sessions
diff --git a/components/unified_consent/unified_consent_metrics.cc b/components/unified_consent/unified_consent_metrics.cc
index b03867c..08da8d6d 100644
--- a/components/unified_consent/unified_consent_metrics.cc
+++ b/components/unified_consent/unified_consent_metrics.cc
@@ -14,11 +14,29 @@
 #include "components/unified_consent/pref_names.h"
 
 namespace unified_consent {
-
 namespace metrics {
 
 namespace {
 
+// Sync data types that can be customized in settings.
+// Used in histograms. Do not change existing values, append new values at the
+// end.
+enum class SyncDataType {
+  kNone = 0,
+  kApps = 1,
+  kBookmarks = 2,
+  kExtensions = 3,
+  kHistory = 4,
+  kSettings = 5,
+  kThemes = 6,
+  kTabs = 7,
+  kPasswords = 8,
+  kAutofill = 9,
+  kPayments = 10,
+
+  kMaxValue = kPayments
+};
+
 typedef std::pair<SyncDataType, syncer::ModelType> DT;
 
 // Records a sample in the SyncAndGoogleServicesSettings histogram. Wrapped in a
@@ -86,5 +104,4 @@
 }
 
 }  // namespace metrics
-
 }  // namespace unified_consent
diff --git a/components/unified_consent/unified_consent_metrics.h b/components/unified_consent/unified_consent_metrics.h
index 7e44105..1431cd1 100644
--- a/components/unified_consent/unified_consent_metrics.h
+++ b/components/unified_consent/unified_consent_metrics.h
@@ -12,7 +12,6 @@
 }
 
 namespace unified_consent {
-
 namespace metrics {
 
 // Google services that can be toggled in user settings.
@@ -30,25 +29,6 @@
   kMaxValue = kAllServicesWereEnabled
 };
 
-// Sync data types that can be customized in settings.
-// Used in histograms. Do not change existing values, append new values at the
-// end.
-enum class SyncDataType {
-  kNone = 0,
-  kApps = 1,
-  kBookmarks = 2,
-  kExtensions = 3,
-  kHistory = 4,
-  kSettings = 5,
-  kThemes = 6,
-  kTabs = 7,
-  kPasswords = 8,
-  kAutofill = 9,
-  kPayments = 10,
-
-  kMaxValue = kPayments
-};
-
 // Records settings entries in the SyncAndGoogleServicesSettings.
 // kNone is recorded when none of the settings is enabled.
 void RecordSettingsHistogram(PrefService* pref_service);
@@ -59,7 +39,6 @@
                                        PrefService* pref_service);
 
 }  // namespace metrics
-
 }  // namespace unified_consent
 
 #endif  // COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_METRICS_H_
diff --git a/components/update_client/BUILD.gn b/components/update_client/BUILD.gn
index 636f40a..a6303eb6 100644
--- a/components/update_client/BUILD.gn
+++ b/components/update_client/BUILD.gn
@@ -26,6 +26,8 @@
     "crx_downloader.cc",
     "crx_downloader.h",
     "crx_update_item.h",
+    "network.cc",
+    "network.h",
     "persisted_data.cc",
     "persisted_data.h",
     "ping_manager.cc",
diff --git a/components/update_client/component.cc b/components/update_client/component.cc
index 59e50fc..c0ea79191 100644
--- a/components/update_client/component.cc
+++ b/components/update_client/component.cc
@@ -20,6 +20,7 @@
 #include "components/update_client/action_runner.h"
 #include "components/update_client/component_unpacker.h"
 #include "components/update_client/configurator.h"
+#include "components/update_client/network.h"
 #include "components/update_client/protocol_definition.h"
 #include "components/update_client/protocol_serializer.h"
 #include "components/update_client/task_traits.h"
@@ -620,7 +621,7 @@
 
   crx_downloader_ = update_context.crx_downloader_factory(
       component.CanDoBackgroundDownload(),
-      update_context.config->URLLoaderFactory());
+      update_context.config->GetNetworkFetcherFactory());
 
   const auto& id = component.id_;
   crx_downloader_->set_progress_callback(
@@ -685,7 +686,7 @@
 
   crx_downloader_ = update_context.crx_downloader_factory(
       component.CanDoBackgroundDownload(),
-      update_context.config->URLLoaderFactory());
+      update_context.config->GetNetworkFetcherFactory());
 
   const auto& id = component.id_;
   crx_downloader_->set_progress_callback(
diff --git a/components/update_client/configurator.h b/components/update_client/configurator.h
index 15ad3f0..02822f2 100644
--- a/components/update_client/configurator.h
+++ b/components/update_client/configurator.h
@@ -13,7 +13,6 @@
 #include "base/callback_forward.h"
 #include "base/containers/flat_map.h"
 #include "base/memory/ref_counted.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
 
 class GURL;
 class PrefService;
@@ -30,6 +29,7 @@
 namespace update_client {
 
 class ActivityDataService;
+class NetworkFetcherFactory;
 class ProtocolHandlerFactory;
 
 using RecoveryCRXElevator = base::OnceCallback<std::tuple<bool, int, int>(
@@ -103,8 +103,7 @@
   // Returns an empty string if no policy is in effect.
   virtual std::string GetDownloadPreference() const = 0;
 
-  virtual scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactory()
-      const = 0;
+  virtual scoped_refptr<NetworkFetcherFactory> GetNetworkFetcherFactory() = 0;
 
   // Returns a new connector to the service manager. That connector is not bound
   // to any thread yet.
diff --git a/components/update_client/crx_downloader.cc b/components/update_client/crx_downloader.cc
index e07f6c6c..a881c865 100644
--- a/components/update_client/crx_downloader.cc
+++ b/components/update_client/crx_downloader.cc
@@ -17,11 +17,11 @@
 #if defined(OS_WIN)
 #include "components/update_client/background_downloader_win.h"
 #endif
+#include "components/update_client/network.h"
 #include "components/update_client/task_traits.h"
 #include "components/update_client/update_client_errors.h"
 #include "components/update_client/url_fetcher_downloader.h"
 #include "components/update_client/utils.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
 
 namespace update_client {
 
@@ -37,10 +37,9 @@
 // which uses the BITS service.
 std::unique_ptr<CrxDownloader> CrxDownloader::Create(
     bool is_background_download,
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+    scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
   std::unique_ptr<CrxDownloader> url_fetcher_downloader =
-      std::make_unique<UrlFetcherDownloader>(nullptr,
-                                             std::move(url_loader_factory));
+      std::make_unique<UrlFetcherDownloader>(nullptr, network_fetcher_factory);
 
 #if defined(OS_WIN)
   if (is_background_download) {
diff --git a/components/update_client/crx_downloader.h b/components/update_client/crx_downloader.h
index 565b8bc..4824e3f 100644
--- a/components/update_client/crx_downloader.h
+++ b/components/update_client/crx_downloader.h
@@ -19,12 +19,10 @@
 #include "base/threading/thread_checker.h"
 #include "url/gurl.h"
 
-namespace network {
-class SharedURLLoaderFactory;
-}
-
 namespace update_client {
 
+class NetworkFetcherFactory;
+
 // Defines a download interface for downloading components, with retrying on
 // fallback urls in case of errors. This class implements a chain of
 // responsibility design pattern. It can give successors in the chain a chance
@@ -75,9 +73,9 @@
   // different urls and different downloaders.
   using ProgressCallback = base::RepeatingCallback<void()>;
 
-  using Factory = std::unique_ptr<CrxDownloader> (*)(
-      bool,
-      scoped_refptr<network::SharedURLLoaderFactory>);
+  using Factory =
+      std::unique_ptr<CrxDownloader> (*)(bool,
+                                         scoped_refptr<NetworkFetcherFactory>);
 
   // Factory method to create an instance of this class and build the
   // chain of responsibility. |is_background_download| specifies that a
@@ -86,7 +84,7 @@
   // code such as file IO operations.
   static std::unique_ptr<CrxDownloader> Create(
       bool is_background_download,
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+      scoped_refptr<NetworkFetcherFactory> network_fetcher_factory);
   virtual ~CrxDownloader();
 
   void set_progress_callback(const ProgressCallback& progress_callback);
diff --git a/components/update_client/crx_downloader_unittest.cc b/components/update_client/crx_downloader_unittest.cc
index 06a7361..a0f55553 100644
--- a/components/update_client/crx_downloader_unittest.cc
+++ b/components/update_client/crx_downloader_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
+#include "components/update_client/network.h"
 #include "components/update_client/update_client_errors.h"
 #include "components/update_client/utils.h"
 #include "net/base/net_errors.h"
@@ -123,7 +124,8 @@
 
   // Do not use the background downloader in these tests.
   crx_downloader_ =
-      CrxDownloader::Create(false, test_shared_url_loader_factory_);
+      CrxDownloader::Create(false, base::MakeRefCounted<NetworkFetcherFactory>(
+                                       test_shared_url_loader_factory_));
   crx_downloader_->set_progress_callback(progress_callback_);
 
   test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
diff --git a/components/update_client/network.cc b/components/update_client/network.cc
new file mode 100644
index 0000000..07b5d24
--- /dev/null
+++ b/components/update_client/network.cc
@@ -0,0 +1,122 @@
+// 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/update_client/network.h"
+
+#include <utility>
+
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+
+namespace {
+
+const net::NetworkTrafficAnnotationTag traffic_annotation =
+    net::DefineNetworkTrafficAnnotation("component_updater_utils", R"(
+        semantics {
+          sender: "Component Updater"
+          description:
+            "The component updater in Chrome is responsible for updating code "
+            "and data modules such as Flash, CrlSet, Origin Trials, etc. These "
+            "modules are updated on cycles independent of the Chrome release "
+            "tracks. It runs in the browser process and communicates with a "
+            "set of servers using the Omaha protocol to find the latest "
+            "versions of components, download them, and register them with the "
+            "rest of Chrome."
+          trigger: "Manual or automatic software updates."
+          data:
+            "Various OS and Chrome parameters such as version, bitness, "
+            "release tracks, etc."
+          destination: GOOGLE_OWNED_SERVICE
+        }
+        policy {
+          cookies_allowed: NO
+          setting: "This feature cannot be disabled."
+          chrome_policy {
+            ComponentUpdatesEnabled {
+              policy_options {mode: MANDATORY}
+              ComponentUpdatesEnabled: false
+            }
+          }
+        })");
+
+}  // namespace
+
+namespace update_client {
+
+NetworkFetcher::NetworkFetcher(
+    scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory,
+    std::unique_ptr<network::ResourceRequest> resource_request)
+    : shared_url_network_factory_(shared_url_network_factory),
+      simple_url_loader_(
+          network::SimpleURLLoader::Create(std::move(resource_request),
+                                           traffic_annotation)) {}
+NetworkFetcher::~NetworkFetcher() = default;
+
+void NetworkFetcher::DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+    network::SimpleURLLoader::BodyAsStringCallback body_as_string_callback) {
+  simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+      shared_url_network_factory_.get(), std::move(body_as_string_callback));
+}
+
+void NetworkFetcher::DownloadToFile(
+    network::SimpleURLLoader::DownloadToFileCompleteCallback
+        download_to_file_complete_callback,
+    const base::FilePath& file_path,
+    int64_t max_body_size) {
+  return simple_url_loader_->DownloadToFile(
+      shared_url_network_factory_.get(),
+      std::move(download_to_file_complete_callback), file_path, max_body_size);
+}
+
+void NetworkFetcher::AttachStringForUpload(
+    const std::string& upload_data,
+    const std::string& upload_content_type) {
+  return simple_url_loader_->AttachStringForUpload(upload_data,
+                                                   upload_content_type);
+}
+
+void NetworkFetcher::SetOnResponseStartedCallback(
+    network::SimpleURLLoader::OnResponseStartedCallback
+        on_response_started_callback) {
+  simple_url_loader_->SetOnResponseStartedCallback(
+      std::move(on_response_started_callback));
+}
+
+void NetworkFetcher::SetAllowPartialResults(bool allow_partial_results) {
+  simple_url_loader_->SetAllowPartialResults(allow_partial_results);
+}
+
+void NetworkFetcher::SetRetryOptions(int max_retries, int retry_mode) {
+  return simple_url_loader_->SetRetryOptions(max_retries, retry_mode);
+}
+
+int NetworkFetcher::NetError() const {
+  return simple_url_loader_->NetError();
+}
+
+const network::ResourceResponseHead* NetworkFetcher::ResponseInfo() const {
+  return simple_url_loader_->ResponseInfo();
+}
+
+const GURL& NetworkFetcher::GetFinalURL() const {
+  return simple_url_loader_->GetFinalURL();
+}
+
+int64_t NetworkFetcher::GetContentSize() const {
+  return simple_url_loader_->GetContentSize();
+}
+
+NetworkFetcherFactory::NetworkFetcherFactory(
+    scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory)
+    : shared_url_network_factory_(shared_url_network_factory) {}
+
+NetworkFetcherFactory::~NetworkFetcherFactory() = default;
+
+std::unique_ptr<NetworkFetcher> NetworkFetcherFactory::Create(
+    std::unique_ptr<network::ResourceRequest> resource_request) const {
+  return std::make_unique<NetworkFetcher>(shared_url_network_factory_,
+                                          std::move(resource_request));
+}
+
+}  // namespace update_client
diff --git a/components/update_client/network.h b/components/update_client/network.h
new file mode 100644
index 0000000..4df514fb
--- /dev/null
+++ b/components/update_client/network.h
@@ -0,0 +1,85 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UPDATE_CLIENT_NETWORK_H_
+#define COMPONENTS_UPDATE_CLIENT_NETWORK_H_
+
+#include <stdint.h>
+
+#include <limits>
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+
+class GURL;
+
+namespace base {
+class FilePath;
+}  // namespace base
+
+namespace network {
+class SharedURLLoaderFactory;
+}  // namespace network
+
+namespace update_client {
+
+class NetworkFetcher {
+ public:
+  NetworkFetcher(
+      scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory,
+      std::unique_ptr<network::ResourceRequest> resource_request);
+  ~NetworkFetcher();
+
+  // These functions are delegating to the corresponding members of
+  // network::SimpleURLLoader.
+  void DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+      network::SimpleURLLoader::BodyAsStringCallback body_as_string_callback);
+  void DownloadToFile(
+      network::SimpleURLLoader::DownloadToFileCompleteCallback
+          download_to_file_complete_callback,
+      const base::FilePath& file_path,
+      int64_t max_body_size = std::numeric_limits<int64_t>::max());
+  void AttachStringForUpload(const std::string& upload_data,
+                             const std::string& upload_content_type);
+  void SetOnResponseStartedCallback(
+      network::SimpleURLLoader::OnResponseStartedCallback
+          on_response_started_callback);
+  void SetAllowPartialResults(bool allow_partial_results);
+  void SetRetryOptions(int max_retries, int retry_mode);
+  int NetError() const;
+  const network::ResourceResponseHead* ResponseInfo() const;
+  const GURL& GetFinalURL() const;
+  int64_t GetContentSize() const;
+
+ private:
+  scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory_;
+  std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
+
+  DISALLOW_COPY_AND_ASSIGN(NetworkFetcher);
+};
+
+class NetworkFetcherFactory : public base::RefCounted<NetworkFetcherFactory> {
+ public:
+  explicit NetworkFetcherFactory(scoped_refptr<network::SharedURLLoaderFactory>
+                                     shared_url_network_factory);
+
+  std::unique_ptr<NetworkFetcher> Create(
+      std::unique_ptr<network::ResourceRequest> resource_request) const;
+
+ protected:
+  friend class base::RefCounted<NetworkFetcherFactory>;
+  virtual ~NetworkFetcherFactory();
+
+ private:
+  scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(NetworkFetcherFactory);
+};
+
+}  // namespace update_client
+
+#endif  // COMPONENTS_UPDATE_CLIENT_NETWORK_H_
diff --git a/components/update_client/request_sender.cc b/components/update_client/request_sender.cc
index aceb8d8..b767cb09 100644
--- a/components/update_client/request_sender.cc
+++ b/components/update_client/request_sender.cc
@@ -15,10 +15,11 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/client_update_protocol/ecdsa.h"
 #include "components/update_client/configurator.h"
+#include "components/update_client/network.h"
 #include "components/update_client/update_client_errors.h"
 #include "components/update_client/utils.h"
 #include "net/http/http_response_headers.h"
-#include "services/network/public/cpp/simple_url_loader.h"
+#include "services/network/public/cpp/resource_response.h"
 
 namespace update_client {
 
@@ -105,12 +106,12 @@
   }
 
   update_client::LoadCompleteCallback callback = base::BindOnce(
-      &RequestSender::OnSimpleURLLoaderComplete, base::Unretained(this), url);
+      &RequestSender::OnNetworkFetcherComplete, base::Unretained(this), url);
 
-  url_loader_ =
-      SendProtocolRequest(url, request_extra_headers_, request_body_,
-                          std::move(callback), config_->URLLoaderFactory());
-  if (!url_loader_)
+  network_fetcher_ = SendProtocolRequest(url, request_extra_headers_,
+                                         request_body_, std::move(callback),
+                                         config_->GetNetworkFetcherFactory());
+  if (!network_fetcher_)
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::BindOnce(&RequestSender::SendInternalComplete,
@@ -157,7 +158,7 @@
   HandleSendError(error, retry_after_sec);
 }
 
-void RequestSender::OnSimpleURLLoaderComplete(
+void RequestSender::OnNetworkFetcherComplete(
     const GURL& original_url,
     std::unique_ptr<std::string> response_body) {
   DCHECK(thread_checker_.CalledOnValidThread());
@@ -165,8 +166,9 @@
   VLOG(1) << "request completed from url: " << original_url.spec();
 
   int response_code = -1;
-  if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) {
-    response_code = url_loader_->ResponseInfo()->headers->response_code();
+  if (network_fetcher_->ResponseInfo() &&
+      network_fetcher_->ResponseInfo()->headers) {
+    response_code = network_fetcher_->ResponseInfo()->headers->response_code();
   }
 
   int fetch_error = -1;
@@ -175,13 +177,13 @@
   } else if (response_code != -1) {
     fetch_error = response_code;
   } else {
-    fetch_error = url_loader_->NetError();
+    fetch_error = network_fetcher_->NetError();
   }
 
   int64_t retry_after_sec(-1);
   if (original_url.SchemeIsCryptographic() && fetch_error > 0) {
     retry_after_sec =
-        GetInt64HeaderValue(url_loader_.get(), kHeaderXRetryAfter);
+        GetInt64HeaderValue(network_fetcher_.get(), kHeaderXRetryAfter);
     retry_after_sec = std::min(retry_after_sec, kMaxRetryAfterSec);
   }
 
@@ -190,7 +192,7 @@
       base::BindOnce(&RequestSender::SendInternalComplete,
                      base::Unretained(this), fetch_error,
                      response_body ? *response_body : std::string(),
-                     GetStringHeaderValue(url_loader_.get(), kHeaderEtag),
+                     GetStringHeaderValue(network_fetcher_.get(), kHeaderEtag),
                      static_cast<int>(retry_after_sec)));
 }
 
@@ -220,12 +222,13 @@
 }
 
 std::string RequestSender::GetStringHeaderValue(
-    const network::SimpleURLLoader* url_loader,
+    const NetworkFetcher* network_fetcher,
     const char* header_name) {
-  DCHECK(url_loader);
-  if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) {
+  DCHECK(network_fetcher);
+  if (network_fetcher->ResponseInfo() &&
+      network_fetcher->ResponseInfo()->headers) {
     std::string etag;
-    return url_loader->ResponseInfo()->headers->EnumerateHeader(
+    return network_fetcher->ResponseInfo()->headers->EnumerateHeader(
                nullptr, header_name, &etag)
                ? etag
                : std::string();
@@ -235,11 +238,12 @@
 }
 
 int64_t RequestSender::GetInt64HeaderValue(
-    const network::SimpleURLLoader* url_loader,
+    const NetworkFetcher* network_fetcher,
     const char* header_name) {
-  DCHECK(url_loader);
-  if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) {
-    return url_loader->ResponseInfo()->headers->GetInt64HeaderValue(
+  DCHECK(network_fetcher);
+  if (network_fetcher->ResponseInfo() &&
+      network_fetcher->ResponseInfo()->headers) {
+    return network_fetcher->ResponseInfo()->headers->GetInt64HeaderValue(
         header_name);
   }
   return -1;
diff --git a/components/update_client/request_sender.h b/components/update_client/request_sender.h
index 2ffdd62..23a3fe7 100644
--- a/components/update_client/request_sender.h
+++ b/components/update_client/request_sender.h
@@ -22,13 +22,10 @@
 class Ecdsa;
 }
 
-namespace network {
-class SimpleURLLoader;
-}
-
 namespace update_client {
 
 class Configurator;
+class NetworkFetcher;
 
 // Sends a request to one of the urls provided. The class implements a chain
 // of responsibility design pattern, where the urls are tried in the order they
@@ -70,17 +67,16 @@
 
   // Returns the string value of a header of the server response or an empty
   // string if the header is not available.
-  static std::string GetStringHeaderValue(
-      const network::SimpleURLLoader* url_loader,
-      const char* header_name);
+  static std::string GetStringHeaderValue(const NetworkFetcher* url_loader,
+                                          const char* header_name);
 
   // Returns the integral value of a header of the server response or -1 if
   // if the header is not available or a conversion error has occured.
-  static int64_t GetInt64HeaderValue(const network::SimpleURLLoader* loader,
+  static int64_t GetInt64HeaderValue(const NetworkFetcher* loader,
                                      const char* header_name);
 
-  void OnSimpleURLLoaderComplete(const GURL& original_url,
-                                 std::unique_ptr<std::string> response_body);
+  void OnNetworkFetcherComplete(const GURL& original_url,
+                                std::unique_ptr<std::string> response_body);
 
   // Implements the error handling and url fallback mechanism.
   void SendInternal();
@@ -107,7 +103,7 @@
 
   std::string public_key_;
   std::vector<GURL>::const_iterator cur_url_;
-  std::unique_ptr<network::SimpleURLLoader> url_loader_;
+  std::unique_ptr<NetworkFetcher> network_fetcher_;
   std::unique_ptr<client_update_protocol::Ecdsa> signer_;
 
   DISALLOW_COPY_AND_ASSIGN(RequestSender);
diff --git a/components/update_client/test_configurator.cc b/components/update_client/test_configurator.cc
index ad2f618..9d2faa4d 100644
--- a/components/update_client/test_configurator.cc
+++ b/components/update_client/test_configurator.cc
@@ -12,6 +12,7 @@
 #include "components/services/patch/public/interfaces/constants.mojom.h"
 #include "components/services/unzip/public/interfaces/constants.mojom.h"
 #include "components/update_client/activity_data_service.h"
+#include "components/update_client/network.h"
 #include "components/update_client/protocol_handler.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/service_manager/public/cpp/connector.h"
@@ -44,7 +45,9 @@
           connector_factory_.RegisterInstance(patch::mojom::kServiceName)),
       test_shared_loader_factory_(
           base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-              &test_url_loader_factory_)) {
+              &test_url_loader_factory_)),
+      network_fetcher_factory_(base::MakeRefCounted<NetworkFetcherFactory>(
+          test_shared_loader_factory_)) {
   connector_factory_.set_ignore_quit_requests(true);
 }
 
@@ -115,9 +118,9 @@
   return download_preference_;
 }
 
-scoped_refptr<network::SharedURLLoaderFactory>
-TestConfigurator::URLLoaderFactory() const {
-  return test_shared_loader_factory_;
+scoped_refptr<NetworkFetcherFactory>
+TestConfigurator::GetNetworkFetcherFactory() {
+  return network_fetcher_factory_;
 }
 
 std::unique_ptr<service_manager::Connector>
diff --git a/components/update_client/test_configurator.h b/components/update_client/test_configurator.h
index 8c7d0e9..d4a404c 100644
--- a/components/update_client/test_configurator.h
+++ b/components/update_client/test_configurator.h
@@ -35,6 +35,7 @@
 namespace update_client {
 
 class ActivityDataService;
+class NetworkFetcherFactory;
 class ProtocolHandlerFactory;
 
 #define POST_INTERCEPT_SCHEME "https"
@@ -90,8 +91,7 @@
   std::string GetOSLongName() const override;
   base::flat_map<std::string, std::string> ExtraRequestParams() const override;
   std::string GetDownloadPreference() const override;
-  scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactory()
-      const override;
+  scoped_refptr<NetworkFetcherFactory> GetNetworkFetcherFactory() override;
   std::unique_ptr<service_manager::Connector> CreateServiceManagerConnector()
       const override;
   bool EnabledDeltas() const override;
@@ -146,6 +146,7 @@
 
   scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
   network::TestURLLoaderFactory test_url_loader_factory_;
+  scoped_refptr<NetworkFetcherFactory> network_fetcher_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(TestConfigurator);
 };
diff --git a/components/update_client/update_client_unittest.cc b/components/update_client/update_client_unittest.cc
index 2f67919e..20e2dd6d 100644
--- a/components/update_client/update_client_unittest.cc
+++ b/components/update_client/update_client_unittest.cc
@@ -28,6 +28,7 @@
 #include "components/prefs/testing_pref_service.h"
 #include "components/update_client/component_unpacker.h"
 #include "components/update_client/crx_update_item.h"
+#include "components/update_client/network.h"
 #include "components/update_client/persisted_data.h"
 #include "components/update_client/ping_manager.h"
 #include "components/update_client/protocol_parser.h"
@@ -280,7 +281,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -445,7 +446,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -646,7 +647,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -854,7 +855,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -993,7 +994,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -1183,7 +1184,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -1474,7 +1475,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -1748,7 +1749,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -1997,7 +1998,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -2216,7 +2217,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -2363,7 +2364,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -2492,7 +2493,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -2626,7 +2627,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -2717,7 +2718,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -2779,7 +2780,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return nullptr;
     }
 
@@ -2911,7 +2912,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -3154,7 +3155,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -3323,7 +3324,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -3478,7 +3479,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -3663,7 +3664,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
@@ -3825,7 +3826,7 @@
    public:
     static std::unique_ptr<CrxDownloader> Create(
         bool is_background_download,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+        scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
       return std::make_unique<MockCrxDownloader>();
     }
 
diff --git a/components/update_client/url_fetcher_downloader.cc b/components/update_client/url_fetcher_downloader.cc
index 6742c810..4b9ec53 100644
--- a/components/update_client/url_fetcher_downloader.cc
+++ b/components/update_client/url_fetcher_downloader.cc
@@ -15,9 +15,9 @@
 #include "base/task/post_task.h"
 #include "base/task/task_traits.h"
 #include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/update_client/network.h"
 #include "components/update_client/utils.h"
 #include "net/base/load_flags.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/resource_response.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/simple_url_loader.h"
@@ -35,9 +35,9 @@
 
 UrlFetcherDownloader::UrlFetcherDownloader(
     std::unique_ptr<CrxDownloader> successor,
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
+    scoped_refptr<NetworkFetcherFactory> network_fetcher_factory)
     : CrxDownloader(std::move(successor)),
-      url_loader_factory_(std::move(url_loader_factory)) {}
+      network_fetcher_factory_(network_fetcher_factory) {}
 
 UrlFetcherDownloader::~UrlFetcherDownloader() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -62,35 +62,6 @@
 void UrlFetcherDownloader::StartURLFetch(const GURL& url) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
-  net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation("url_fetcher_downloader", R"(
-        semantics {
-          sender: "Component Updater"
-          description:
-            "The component updater in Chrome is responsible for updating code "
-            "and data modules such as Flash, CrlSet, Origin Trials, etc. These "
-            "modules are updated on cycles independent of the Chrome release "
-            "tracks. It runs in the browser process and communicates with a "
-            "set of servers using the Omaha protocol to find the latest "
-            "versions of components, download them, and register them with the "
-            "rest of Chrome."
-          trigger: "Manual or automatic software updates."
-          data:
-            "The URL that refers to a component. It is obfuscated for most "
-            "components."
-          destination: GOOGLE_OWNED_SERVICE
-        }
-        policy {
-          cookies_allowed: NO
-          setting: "This feature cannot be disabled."
-          chrome_policy {
-            ComponentUpdatesEnabled {
-              policy_options {mode: MANDATORY}
-              ComponentUpdatesEnabled: false
-            }
-          }
-        })");
-
   if (download_dir_.empty()) {
     Result result;
     result.error = -1;
@@ -117,32 +88,32 @@
   resource_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
                                  net::LOAD_DO_NOT_SAVE_COOKIES |
                                  net::LOAD_DISABLE_CACHE;
-  url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
-                                                 traffic_annotation);
+  network_fetcher_ =
+      network_fetcher_factory_->Create(std::move(resource_request));
+
   const int kMaxRetries = 3;
-  url_loader_->SetRetryOptions(
+  network_fetcher_->SetRetryOptions(
       kMaxRetries,
       network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE);
 
-  url_loader_->SetOnResponseStartedCallback(base::BindOnce(
+  network_fetcher_->SetOnResponseStartedCallback(base::BindOnce(
       &UrlFetcherDownloader::OnResponseStarted, base::Unretained(this)));
 
   // For the end-to-end system it is important that the client reports the
   // number of bytes it loaded from the server even in the case that the
   // overall network transaction failed.
-  url_loader_->SetAllowPartialResults(true);
+  network_fetcher_->SetAllowPartialResults(true);
 
   VLOG(1) << "Starting background download: " << url.spec();
-  url_loader_->DownloadToFile(
-      url_loader_factory_.get(),
-      base::BindOnce(&UrlFetcherDownloader::OnURLLoadComplete,
+  network_fetcher_->DownloadToFile(
+      base::BindOnce(&UrlFetcherDownloader::OnNetworkFetcherComplete,
                      base::Unretained(this)),
       response);
 
   download_start_time_ = base::TimeTicks::Now();
 }
 
-void UrlFetcherDownloader::OnURLLoadComplete(base::FilePath file_path) {
+void UrlFetcherDownloader::OnNetworkFetcherComplete(base::FilePath file_path) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   const base::TimeTicks download_end_time(base::TimeTicks::Now());
@@ -155,8 +126,9 @@
   // the request and avoid overloading the server in this case.
   // is not accepting requests for the moment.
   int response_code = -1;
-  if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) {
-    response_code = url_loader_->ResponseInfo()->headers->response_code();
+  if (network_fetcher_->ResponseInfo() &&
+      network_fetcher_->ResponseInfo()->headers) {
+    response_code = network_fetcher_->ResponseInfo()->headers->response_code();
   }
 
   int fetch_error = -1;
@@ -165,7 +137,7 @@
   } else if (response_code != -1) {
     fetch_error = response_code;
   } else {
-    fetch_error = url_loader_->NetError();
+    fetch_error = network_fetcher_->NetError();
   }
 
   const bool is_handled = fetch_error == 0 || IsHttpServerError(fetch_error);
@@ -182,15 +154,15 @@
   download_metrics.error = fetch_error;
   // Tests expected -1, in case of failures and no content is available.
   download_metrics.downloaded_bytes =
-      fetch_error && !url_loader_->GetContentSize()
+      fetch_error && !network_fetcher_->GetContentSize()
           ? -1
-          : url_loader_->GetContentSize();
+          : network_fetcher_->GetContentSize();
   download_metrics.total_bytes = total_bytes_;
   download_metrics.download_time_ms = download_time.InMilliseconds();
 
-  VLOG(1) << "Downloaded " << url_loader_->GetContentSize() << " bytes in "
+  VLOG(1) << "Downloaded " << network_fetcher_->GetContentSize() << " bytes in "
           << download_time.InMilliseconds() << "ms from "
-          << url_loader_->GetFinalURL().spec() << " to "
+          << network_fetcher_->GetFinalURL().spec() << " to "
           << result.response.value();
 
   // Delete the download directory in the error cases.
diff --git a/components/update_client/url_fetcher_downloader.h b/components/update_client/url_fetcher_downloader.h
index 03fee0a..6a1653c 100644
--- a/components/update_client/url_fetcher_downloader.h
+++ b/components/update_client/url_fetcher_downloader.h
@@ -17,19 +17,20 @@
 #include "components/update_client/crx_downloader.h"
 
 namespace network {
-class SharedURLLoaderFactory;
-class SimpleURLLoader;
 struct ResourceResponseHead;
 }  // namespace network
 
 namespace update_client {
 
-// Implements a CRX downloader in top of the SimpleURLLoader.
+class NetworkFetcher;
+class NetworkFetcherFactory;
+
+// Implements a CRX downloader using a NetworkFetcher object.
 class UrlFetcherDownloader : public CrxDownloader {
  public:
   UrlFetcherDownloader(
       std::unique_ptr<CrxDownloader> successor,
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+      scoped_refptr<NetworkFetcherFactory> network_fetcher_factory);
   ~UrlFetcherDownloader() override;
 
  private:
@@ -38,13 +39,13 @@
 
   void CreateDownloadDir();
   void StartURLFetch(const GURL& url);
-  void OnURLLoadComplete(base::FilePath file_path);
+  void OnNetworkFetcherComplete(base::FilePath file_path);
   void OnResponseStarted(const GURL& final_url,
                          const network::ResourceResponseHead& response_head);
   THREAD_CHECKER(thread_checker_);
 
-  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
-  std::unique_ptr<network::SimpleURLLoader> url_loader_;
+  scoped_refptr<NetworkFetcherFactory> network_fetcher_factory_;
+  std::unique_ptr<NetworkFetcher> network_fetcher_;
 
   // Contains a temporary download directory for the downloaded file.
   base::FilePath download_dir_;
diff --git a/components/update_client/utils.cc b/components/update_client/utils.cc
index 34dc92c..18a2453 100644
--- a/components/update_client/utils.cc
+++ b/components/update_client/utils.cc
@@ -24,54 +24,25 @@
 #include "components/data_use_measurement/core/data_use_user_data.h"
 #include "components/update_client/component.h"
 #include "components/update_client/configurator.h"
+#include "components/update_client/network.h"
 #include "components/update_client/update_client.h"
 #include "components/update_client/update_client_errors.h"
 #include "crypto/secure_hash.h"
 #include "crypto/sha2.h"
 #include "net/base/load_flags.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/simple_url_loader.h"
 #include "url/gurl.h"
 
 namespace update_client {
 
-std::unique_ptr<network::SimpleURLLoader> SendProtocolRequest(
+std::unique_ptr<NetworkFetcher> SendProtocolRequest(
     const GURL& url,
     const base::flat_map<std::string, std::string>&
         protocol_request_extra_headers,
     const std::string& protocol_request,
     network::SimpleURLLoader::BodyAsStringCallback callback,
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
-  net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation("component_updater_utils", R"(
-        semantics {
-          sender: "Component Updater"
-          description:
-            "The component updater in Chrome is responsible for updating code "
-            "and data modules such as Flash, CrlSet, Origin Trials, etc. These "
-            "modules are updated on cycles independent of the Chrome release "
-            "tracks. It runs in the browser process and communicates with a "
-            "set of servers using the Omaha protocol to find the latest "
-            "versions of components, download them, and register them with the "
-            "rest of Chrome."
-          trigger: "Manual or automatic software updates."
-          data:
-            "Various OS and Chrome parameters such as version, bitness, "
-            "release tracks, etc."
-          destination: GOOGLE_OWNED_SERVICE
-        }
-        policy {
-          cookies_allowed: NO
-          setting: "This feature cannot be disabled."
-          chrome_policy {
-            ComponentUpdatesEnabled {
-              policy_options {mode: MANDATORY}
-              ComponentUpdatesEnabled: false
-            }
-          }
-        })");
-  // Create and initialize URL loader.
+    scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
   auto resource_request = std::make_unique<network::ResourceRequest>();
   resource_request->url = url;
   resource_request->method = "POST";
@@ -80,17 +51,16 @@
                                  net::LOAD_DISABLE_CACHE;
   for (const auto& header : protocol_request_extra_headers)
     resource_request->headers.SetHeader(header.first, header.second);
-
-  auto simple_loader = network::SimpleURLLoader::Create(
-      std::move(resource_request), traffic_annotation);
+  auto network_fetcher =
+      network_fetcher_factory->Create(std::move(resource_request));
   const int max_retry_on_network_change = 3;
-  simple_loader->SetRetryOptions(
+  network_fetcher->SetRetryOptions(
       max_retry_on_network_change,
       network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
-  simple_loader->AttachStringForUpload(protocol_request, "application/xml");
-  simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
-      url_loader_factory.get(), std::move(callback));
-  return simple_loader;
+  network_fetcher->AttachStringForUpload(protocol_request, "application/xml");
+  network_fetcher->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+      std::move(callback));
+  return network_fetcher;
 }
 
 bool HasDiffUpdate(const Component& component) {
diff --git a/components/update_client/utils.h b/components/update_client/utils.h
index 77fc76c..70872b30 100644
--- a/components/update_client/utils.h
+++ b/components/update_client/utils.h
@@ -22,14 +22,11 @@
 class FilePath;
 }
 
-namespace network {
-class SharedURLLoaderFactory;
-class SimpleURLLoader;
-}  // namespace network
-
 namespace update_client {
 
 class Component;
+class NetworkFetcher;
+class NetworkFetcherFactory;
 struct CrxComponent;
 
 // Defines a name-value pair that represents an installer attribute.
@@ -43,13 +40,13 @@
 // Sends a protocol request to the the service endpoint specified by |url|.
 // The body of the request is provided by |protocol_request| and it is
 // expected to contain XML data. The caller owns the returned object.
-std::unique_ptr<network::SimpleURLLoader> SendProtocolRequest(
+std::unique_ptr<NetworkFetcher> SendProtocolRequest(
     const GURL& url,
     const base::flat_map<std::string, std::string>&
         protocol_request_extra_headers,
     const std::string& protocol_request,
     LoadCompleteCallback callback,
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+    scoped_refptr<NetworkFetcherFactory> network_fetcher_factory);
 
 // Returns true if the |component| contains a valid differential update url.
 bool HasDiffUpdate(const Component& component);
diff --git a/content/browser/android/content_feature_list.cc b/content/browser/android/content_feature_list.cc
index 538ef50a..4d1b275 100644
--- a/content/browser/android/content_feature_list.cc
+++ b/content/browser/android/content_feature_list.cc
@@ -24,6 +24,7 @@
 const base::Feature* kFeaturesExposedToJava[] = {
     &features::kBackgroundMediaRendererHasModerateBinding,
     &kEnhancedSelectionInsertionHandle,
+    &features::kServiceWorkerForegroundPriority,
 };
 
 const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) {
diff --git a/content/browser/browser_thread_browsertest.cc b/content/browser/browser_thread_browsertest.cc
index 9903124d..6be9acf 100644
--- a/content/browser/browser_thread_browsertest.cc
+++ b/content/browser/browser_thread_browsertest.cc
@@ -46,8 +46,8 @@
   }
 };
 
-// Flaky on Chrome OS. https://crbug.com/910834
-#if defined(OS_CHROMEOS)
+// Flaky on Chrome OS and Linux. https://crbug.com/910834
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 #define MAYBE_ExpectFailures DISABLED_ExpectFailures
 #else
 #define MAYBE_ExpectFailures ExpectFailures
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc
index 2840f2e..e4fe19f7 100644
--- a/content/browser/child_process_launcher.cc
+++ b/content/browser/child_process_launcher.cc
@@ -15,6 +15,7 @@
 #include "base/process/launch.h"
 #include "build/build_config.h"
 #include "content/public/browser/child_process_launcher_utils.h"
+#include "content/public/common/content_features.h"
 #include "content/public/common/sandboxed_process_launcher_delegate.h"
 #include "services/service_manager/embedder/result_codes.h"
 
@@ -167,10 +168,18 @@
   return ret;
 }
 
+bool ChildProcessLauncherPriority::is_background() const {
+  return !visible && !has_media_stream && !boost_for_pending_views &&
+         !(has_foreground_service_worker &&
+           base::FeatureList::IsEnabled(
+               features::kServiceWorkerForegroundPriority));
+}
+
 bool ChildProcessLauncherPriority::operator==(
     const ChildProcessLauncherPriority& other) const {
   return visible == other.visible &&
          has_media_stream == other.has_media_stream &&
+         has_foreground_service_worker == other.has_foreground_service_worker &&
          frame_depth == other.frame_depth &&
          intersects_viewport == other.intersects_viewport &&
          boost_for_pending_views == other.boost_for_pending_views
diff --git a/content/browser/child_process_launcher.h b/content/browser/child_process_launcher.h
index e081b04..5ecd927 100644
--- a/content/browser/child_process_launcher.h
+++ b/content/browser/child_process_launcher.h
@@ -58,6 +58,7 @@
 struct ChildProcessLauncherPriority {
   ChildProcessLauncherPriority(bool visible,
                                bool has_media_stream,
+                               bool has_foreground_service_worker,
                                unsigned int frame_depth,
                                bool intersects_viewport,
                                bool boost_for_pending_views
@@ -68,6 +69,7 @@
                                )
       : visible(visible),
         has_media_stream(has_media_stream),
+        has_foreground_service_worker(has_foreground_service_worker),
         frame_depth(frame_depth),
         intersects_viewport(intersects_viewport),
         boost_for_pending_views(boost_for_pending_views)
@@ -79,9 +81,7 @@
   }
 
   // Returns true if the child process is backgrounded.
-  bool is_background() const {
-    return !visible && !has_media_stream && !boost_for_pending_views;
-  }
+  bool is_background() const;
 
   bool operator==(const ChildProcessLauncherPriority& other) const;
   bool operator!=(const ChildProcessLauncherPriority& other) const {
@@ -101,6 +101,11 @@
   // content.
   bool has_media_stream;
 
+  // |has_foreground_service_worker| is true when the process has a service
+  // worker that may need to service timely events from other, possibly visible,
+  // processes.
+  bool has_foreground_service_worker;
+
   // |frame_depth| is the depth of the shallowest frame this process is
   // responsible for which has |visible| visibility. It only makes sense to
   // compare this property for two ChildProcessLauncherPriority instances with
diff --git a/content/browser/child_process_launcher_helper_android.cc b/content/browser/child_process_launcher_helper_android.cc
index ec221f59..9073e88 100644
--- a/content/browser/child_process_launcher_helper_android.cc
+++ b/content/browser/child_process_launcher_helper_android.cc
@@ -227,9 +227,9 @@
   DCHECK(env);
   return Java_ChildProcessLauncherHelperImpl_setPriority(
       env, java_peer_, process.Handle(), priority.visible,
-      priority.has_media_stream, priority.frame_depth,
-      priority.intersects_viewport, priority.boost_for_pending_views,
-      static_cast<jint>(priority.importance));
+      priority.has_media_stream, priority.has_foreground_service_worker,
+      priority.frame_depth, priority.intersects_viewport,
+      priority.boost_for_pending_views, static_cast<jint>(priority.importance));
 }
 
 // static
diff --git a/content/browser/font_unique_name_lookup/font_unique_name_lookup_unittest.cc b/content/browser/font_unique_name_lookup/font_unique_name_lookup_unittest.cc
index bc13d1e..329da1f 100644
--- a/content/browser/font_unique_name_lookup/font_unique_name_lookup_unittest.cc
+++ b/content/browser/font_unique_name_lookup/font_unique_name_lookup_unittest.cc
@@ -98,7 +98,13 @@
   ASSERT_GT(matcher_after_load.AvailableFonts(), 0u);
 }
 
-TEST_F(FontUniqueNameLookupTest, TestHandleFailedRead) {
+// http://crbug.com/928818
+#if defined(ADDRESS_SANITIZER)
+#define MAYBE_TestHandleFiledRead DISABLED_TestHandleFailedRead
+#else
+#define MAYBE_TestHandleFiledRead TestHandleFailedRead
+#endif
+TEST_F(FontUniqueNameLookupTest, MAYBE_TestHandleFiledRead) {
   base::DeleteFile(font_unique_name_lookup_->TableCacheFilePathForTesting(),
                    false);
   ASSERT_FALSE(font_unique_name_lookup_->LoadFromFile());
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 5714b54..2046b6f8 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -2540,6 +2540,12 @@
     ReloadType reload_type,
     std::vector<std::unique_ptr<NavigationRequest>>* same_document_loads,
     std::vector<std::unique_ptr<NavigationRequest>>* different_document_loads) {
+  // A frame pending deletion is not allowed to navigate anymore. It has been
+  // deleted and the browser already committed to destroying this
+  // RenderFrameHost. See https://crbug.com/930278.
+  if (!frame->current_frame_host()->is_active())
+    return;
+
   DCHECK(pending_entry_);
   DCHECK_GE(last_committed_entry_index_, 0);
   FrameNavigationEntry* new_item = pending_entry_->GetFrameEntry(frame);
diff --git a/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc b/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
index b730cee3..803c9577 100644
--- a/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
@@ -83,9 +83,11 @@
       const std::vector<std::string>& origins) {
     blink::ParsedFeaturePolicy result(1);
     result[0].feature = feature;
-    result[0].matches_all_origins = false;
+    // TODO(loonybear): Add a test for non-bool type PolicyValue.
+    // crbug.com/924568.
     for (const std::string& origin : origins)
-      result[0].origins.push_back(url::Origin::Create(GURL(origin)));
+      result[0].values.insert(std::pair<url::Origin, blink::PolicyValue>(
+          url::Origin::Create(GURL(origin)), blink::PolicyValue(true)));
     return result;
   }
 };
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 1d63f90..fb7bb73 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2829,8 +2829,12 @@
 
 bool RenderFrameHostImpl::IsFeatureEnabled(
     blink::mojom::FeaturePolicyFeature feature) {
-  return feature_policy_ && feature_policy_->IsFeatureEnabledForOrigin(
-                                feature, GetLastCommittedOrigin());
+  blink::mojom::PolicyValueType feature_type =
+      feature_policy_->GetFeatureList().at(feature).second;
+  return feature_policy_ &&
+         feature_policy_->IsFeatureEnabledForOrigin(
+             feature, GetLastCommittedOrigin(),
+             blink::PolicyValue::CreateMaxPolicyValue(feature_type));
 }
 
 void RenderFrameHostImpl::ViewSource() {
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index ee7ee849..11643f5 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -517,9 +517,7 @@
   // See https://crbug.com/926820 and https://crbug.com/927705.
   if (!current_frame_host()->is_active()) {
     NOTREACHED() << "Navigation in an inactive frame";
-    NavigationHandle* handle = request.navigation_handle();
-    DEBUG_ALIAS_FOR_GURL(url_from, handle->GetPreviousURL())
-    DEBUG_ALIAS_FOR_GURL(url_to, handle->GetURL())
+    DEBUG_ALIAS_FOR_GURL(url, request.common_params().url);
     base::debug::DumpWithoutCrashing();
   }
 
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index b39aa13..a6d373e19 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -252,6 +252,7 @@
     switches::kUseCmdDecoder,
     switches::kForceVideoOverlays,
 #if defined(OS_ANDROID)
+    switches::kEnableReachedCodeProfiler,
     switches::kOrderfileMemoryOptimization,
 #endif
     switches::kWebglAntialiasingMode,
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 9045c813..6a00a7d5 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1481,6 +1481,7 @@
       visible_clients_(0),
       priority_(!blink::kLaunchingProcessIsBackgrounded,
                 false /* has_media_stream */,
+                false /* has_foreground_service_worker */,
                 frame_depth_,
                 false /* intersects_viewport */,
                 true /* boost_for_pending_views */
@@ -2665,6 +2666,17 @@
   UpdateProcessPriority();
 }
 
+void RenderProcessHostImpl::OnForegroundServiceWorkerAdded() {
+  foreground_service_worker_count_ += 1;
+  UpdateProcessPriority();
+}
+
+void RenderProcessHostImpl::OnForegroundServiceWorkerRemoved() {
+  DCHECK_GT(foreground_service_worker_count_, 0);
+  foreground_service_worker_count_ -= 1;
+  UpdateProcessPriority();
+}
+
 // static
 void RenderProcessHostImpl::set_render_process_host_factory_for_testing(
     const RenderProcessHostFactory* rph_factory) {
@@ -3084,6 +3096,7 @@
     switches::kDisallowNonExactResourceReuse,
 #if defined(OS_ANDROID)
     switches::kDisableMediaSessionAPI,
+    switches::kEnableReachedCodeProfiler,
     switches::kOrderfileMemoryOptimization,
     switches::kRendererWaitForJavaDebugger,
 #endif
@@ -4326,7 +4339,8 @@
   const ChildProcessLauncherPriority priority(
       visible_clients_ > 0 || base::CommandLine::ForCurrentProcess()->HasSwitch(
                                   switches::kDisableRendererBackgrounding),
-      media_stream_count_ > 0, frame_depth_, intersects_viewport_,
+      media_stream_count_ > 0, foreground_service_worker_count_ > 0,
+      frame_depth_, intersects_viewport_,
       !!pending_views_ /* boost_for_pending_views */
 #if defined(OS_ANDROID)
       ,
@@ -4363,6 +4377,13 @@
   if (!run_renderer_in_process()) {
     DCHECK(child_process_launcher_.get());
     DCHECK(!child_process_launcher_->IsStarting());
+    // Make sure to keep the pid in the trace so we can tell which process is
+    // being modified.
+    TRACE_EVENT2(
+        "renderer_host",
+        "RenderProcessHostImpl::UpdateProcessPriority.SetProcessPriority",
+        "pid", child_process_launcher_->GetProcess().Pid(),
+        "priority_is_background", priority.is_background());
     child_process_launcher_->SetProcessPriority(priority_);
   }
 
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 83933c1..d5d82b53 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -418,6 +418,9 @@
   void OnMediaStreamRemoved() override;
   int get_media_stream_count_for_testing() const { return media_stream_count_; }
 
+  void OnForegroundServiceWorkerAdded() override;
+  void OnForegroundServiceWorkerRemoved() override;
+
   // Sets the global factory used to create new RenderProcessHosts in unit
   // tests.  It may be nullptr, in which case the default RenderProcessHost will
   // be created (this is the behavior if you don't call this function).  The
@@ -893,6 +896,11 @@
   // determine if if a process should be backgrounded.
   int media_stream_count_ = 0;
 
+  // Tracks service workers that may need to respond to events from other
+  // processes in a timely manner.  Used to determine if a process should
+  // not be backgrounded.
+  int foreground_service_worker_count_ = 0;
+
   // A WeakPtrFactory which is reset every time Cleanup() runs. Used to vend
   // WeakPtrs which are invalidated any time the RPHI is recycled.
   std::unique_ptr<base::WeakPtrFactory<RenderProcessHostImpl>>
diff --git a/content/browser/scheduler/responsiveness/watcher_unittest.cc b/content/browser/scheduler/responsiveness/watcher_unittest.cc
index 2af17fed..bb392e4 100644
--- a/content/browser/scheduler/responsiveness/watcher_unittest.cc
+++ b/content/browser/scheduler/responsiveness/watcher_unittest.cc
@@ -89,7 +89,7 @@
   int NumTasksOnIOThread() { return calculator_->NumTasksOnIOThread(); }
 
  private:
-  ~FakeWatcher() override{};
+  ~FakeWatcher() override {}
   FakeCalculator* calculator_ = nullptr;
   bool register_message_loop_observer_ = false;
 };
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index 876b7db..706e2c5d 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -33,6 +33,7 @@
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/common/child_process_host.h"
 #include "content/public/common/content_client.h"
+#include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "ipc/ipc_message.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
@@ -325,6 +326,21 @@
   return false;
 }
 
+void NotifyForegroundServiceWorkerOnUIThread(bool added, int process_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(
+      base::FeatureList::IsEnabled(features::kServiceWorkerForegroundPriority));
+
+  RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
+  if (!rph)
+    return;
+
+  if (added)
+    rph->OnForegroundServiceWorkerAdded();
+  else
+    rph->OnForegroundServiceWorkerRemoved();
+}
+
 }  // namespace
 
 // Created on UI thread and moved to IO thread. Proxies notifications to
@@ -648,7 +664,7 @@
   devtools_proxy_.reset();
   if (registry_->GetWorker(embedded_worker_id_))
     registry_->RemoveWorker(process_id(), embedded_worker_id_);
-  process_handle_.reset();
+  ReleaseProcess();
 }
 
 void EmbeddedWorkerInstance::Start(
@@ -748,6 +764,7 @@
       instance_host_binding_(this),
       devtools_attached_(false),
       network_accessed_for_script_(false),
+      foreground_notified_(false),
       weak_factory_(this) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 }
@@ -759,6 +776,9 @@
   DCHECK(!process_handle_);
 
   process_handle_ = std::move(handle);
+
+  UpdateForegroundPriority();
+
   start_situation_ = start_situation;
   for (auto& observer : listener_list_)
     observer.OnProcessAllocated();
@@ -955,6 +975,16 @@
     observer.OnDetached(old_status);
 }
 
+void EmbeddedWorkerInstance::UpdateForegroundPriority() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  if (process_handle_ &&
+      owner_version_->ShouldRequireForegroundPriority(process_id())) {
+    NotifyForegroundServiceWorkerAdded();
+  } else {
+    NotifyForegroundServiceWorkerRemoved();
+  }
+}
+
 base::WeakPtr<EmbeddedWorkerInstance> EmbeddedWorkerInstance::AsWeakPtr() {
   return weak_factory_.GetWeakPtr();
 }
@@ -1020,6 +1050,8 @@
   // Abort an inflight start task.
   inflight_start_task_.reset();
 
+  NotifyForegroundServiceWorkerRemoved();
+
   instance_host_binding_.Close();
   devtools_proxy_.reset();
   process_handle_.reset();
@@ -1101,4 +1133,37 @@
   GetNetworkFactoryCallbackForTest() = create_network_factory_callback;
 }
 
+void EmbeddedWorkerInstance::NotifyForegroundServiceWorkerAdded() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(
+      base::FeatureList::IsEnabled(features::kServiceWorkerForegroundPriority));
+
+  if (!process_handle_ || foreground_notified_)
+    return;
+
+  foreground_notified_ = true;
+
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::UI},
+      base::BindOnce(&NotifyForegroundServiceWorkerOnUIThread, true /* added */,
+                     process_id()));
+}
+
+void EmbeddedWorkerInstance::NotifyForegroundServiceWorkerRemoved() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(
+      !foreground_notified_ ||
+      base::FeatureList::IsEnabled(features::kServiceWorkerForegroundPriority));
+
+  if (!process_handle_ || !foreground_notified_)
+    return;
+
+  foreground_notified_ = false;
+
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::UI},
+      base::BindOnce(&NotifyForegroundServiceWorkerOnUIThread,
+                     false /* added */, process_id()));
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index 6396910..e61b7f2c 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -217,6 +217,11 @@
   // worker.
   void Detach();
 
+  // Examine the current state of the worker in order to determine if it should
+  // require foreground priority or not.  This should be called whenever state
+  // changes such that the decision might change.
+  void UpdateForegroundPriority();
+
   base::WeakPtr<EmbeddedWorkerInstance> AsWeakPtr();
 
  private:
@@ -295,6 +300,11 @@
   void OnSetupFailed(StatusCallback callback,
                      blink::ServiceWorkerStatusCode status);
 
+  // Called when a foreground service worker is added/removed in a process.
+  // Called on the IO thread and dispatches task to the UI thread.
+  void NotifyForegroundServiceWorkerAdded();
+  void NotifyForegroundServiceWorkerRemoved();
+
   base::WeakPtr<ServiceWorkerContextCore> context_;
   scoped_refptr<EmbeddedWorkerRegistry> registry_;
   ServiceWorkerVersion* owner_version_;
@@ -325,6 +335,10 @@
   // served from HTTPCache or ServiceWorkerDatabase this value is false.
   bool network_accessed_for_script_;
 
+  // True if the RenderProcessHost has been notified that this is a service
+  // worker requiring foreground priority.
+  bool foreground_notified_;
+
   ListenerList listener_list_;
   std::unique_ptr<DevToolsProxy> devtools_proxy_;
 
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 77b066e..c5b62a2 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -701,7 +701,11 @@
   const std::string& uuid = provider_host->client_uuid();
   CHECK(!provider_host->client_uuid().empty());
   DCHECK(!base::ContainsKey(controllee_map_, uuid));
+
   controllee_map_[uuid] = provider_host;
+
+  embedded_worker_->UpdateForegroundPriority();
+
   // Keep the worker alive a bit longer right after a new controllee is added.
   RestartTick(&idle_time_);
   ClearTick(&no_controllees_time_);
@@ -727,6 +731,9 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(base::ContainsKey(controllee_map_, client_uuid));
   controllee_map_.erase(client_uuid);
+
+  embedded_worker_->UpdateForegroundPriority();
+
   // Notify observers asynchronously since this gets called during
   // ServiceWorkerProviderHost's destructor, and we don't want observers to do
   // work during that.
@@ -2133,4 +2140,38 @@
   return std::move(compared_script_info_map_[script_url].paused_state);
 }
 
+bool ServiceWorkerVersion::ShouldRequireForegroundPriority(
+    int worker_process_id) const {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!base::FeatureList::IsEnabled(features::kServiceWorkerForegroundPriority))
+    return false;
+
+  // Currently FetchEvents are the only type of event we need to really process
+  // at foreground priority.  If the service worker does not have a FetchEvent
+  // handler then we can always allow it to go to the background.
+  if (fetch_handler_existence_ != FetchHandlerExistence::EXISTS)
+    return false;
+
+  // Keep the service worker at foreground priority if its controlling clients
+  // from a different process.  In this situation we are likely to need to
+  // quickly service FetchEvents when the worker's process does not have any
+  // visible windows and would have otherwise been moved to the background.
+  //
+  // Ideally we would check the visibility of all clients as well, but that
+  // would also require triggering additional checks on every visibility
+  // change of all clients.  That would add a lot of complexity and its
+  // unclear we need to pay that cost yet.  This may get easier once the
+  // service worker code runs on the UI thread directly. (crbug.com/824858)
+  //
+  // For now the requirement for cross-process clients should filter out most
+  // service workers.  The impact of foreground service workers is further
+  // limited by the automatic shutdown mechanism.
+  for (const auto& controllee : controllee_map_) {
+    const ServiceWorkerProviderHost* host = controllee.second;
+    if (host->process_id() != worker_process_id)
+      return true;
+  }
+  return false;
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 3b8282d..aebb003 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -525,6 +525,10 @@
   std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker::PausedState>
   TakePausedStateOfChangedScript(const GURL& script_url);
 
+  // Called by the EmbeddedWorkerInstance to determine if its worker process
+  // should be kept at foreground priority.
+  bool ShouldRequireForegroundPriority(int worker_process_id) const;
+
  private:
   friend class base::RefCounted<ServiceWorkerVersion>;
   friend class EmbeddedWorkerInstanceTest;
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index cc180ef3..76fa74a 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/time/time.h"
 #include "content/browser/service_worker/embedded_worker_registry.h"
@@ -26,6 +27,7 @@
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_test_utils.h"
 #include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/content_features.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_service.mojom.h"
@@ -169,8 +171,7 @@
     version_->script_cache_map()->SetResources(records);
     version_->SetMainScriptHttpResponseInfo(
         EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
-    version_->set_fetch_handler_existence(
-        ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+    version_->set_fetch_handler_existence(GetFetchHandlerExistence());
 
     // Make the registration findable via storage functions.
     base::Optional<blink::ServiceWorkerStatusCode> status;
@@ -225,6 +226,29 @@
     version_->SetTickClockForTesting(tick_clock);
   }
 
+  virtual ServiceWorkerVersion::FetchHandlerExistence GetFetchHandlerExistence()
+      const {
+    return ServiceWorkerVersion::FetchHandlerExistence::EXISTS;
+  }
+
+  std::unique_ptr<ServiceWorkerProviderHost> ActivateWithControllee(
+      int controllee_process_id = 33) {
+    version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+    registration_->SetActiveVersion(version_);
+    ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+    std::unique_ptr<ServiceWorkerProviderHost> host =
+        CreateProviderHostForWindow(
+            controllee_process_id, 1 /* dummy provider_id */,
+            true /* is_parent_frame_secure */, helper_->context()->AsWeakPtr(),
+            &remote_endpoint);
+    host->UpdateUrls(registration_->scope(), registration_->scope());
+    host->SetControllerRegistration(registration_,
+                                    false /* notify_controllerchange */);
+    EXPECT_TRUE(version_->HasControllee());
+    EXPECT_TRUE(host->controller());
+    return host;
+  }
+
   TestBrowserThreadBundle thread_bundle_;
   std::unique_ptr<MessageReceiver> helper_;
   scoped_refptr<ServiceWorkerRegistration> registration_;
@@ -1333,6 +1357,135 @@
   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorDisallowed, status.value());
 }
 
+TEST_F(ServiceWorkerVersionTest,
+       ForegroundServiceWorkerCountUpdatedByControllee) {
+  base::test::ScopedFeatureList scoped_list;
+  scoped_list.InitAndEnableFeature(features::kServiceWorkerForegroundPriority);
+
+  // Start the worker before we have a controllee.
+  base::Optional<blink::ServiceWorkerStatusCode> status;
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
+  EXPECT_EQ(
+      0,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+
+  // Add a controllee in a different process from the service worker.
+  auto host = ActivateWithControllee();
+
+  // RenderProcessHost should be notified of foreground worker.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(
+      1,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+
+  // Remove the controllee.
+  host.reset();
+  EXPECT_FALSE(version_->HasControllee());
+
+  // RenderProcessHost should be notified that there are no foreground workers.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(
+      0,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+}
+
+TEST_F(ServiceWorkerVersionTest,
+       ForegroundServiceWorkerCountNotUpdatedBySameProcessControllee) {
+  base::test::ScopedFeatureList scoped_list;
+  scoped_list.InitAndEnableFeature(features::kServiceWorkerForegroundPriority);
+
+  // Start the worker before we have a controllee.
+  base::Optional<blink::ServiceWorkerStatusCode> status;
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
+  EXPECT_EQ(
+      0,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+
+  // Add a controllee in the same process as the service worker.
+  auto host = ActivateWithControllee(version_->embedded_worker()->process_id());
+
+  // RenderProcessHost should be notified of foreground worker.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(
+      0,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+}
+
+TEST_F(ServiceWorkerVersionTest,
+       ForegroundServiceWorkerCountUpdatedByWorkerStatus) {
+  base::test::ScopedFeatureList scoped_list;
+  scoped_list.InitAndEnableFeature(features::kServiceWorkerForegroundPriority);
+
+  // Add a controllee in a different process from the service worker.
+  auto host = ActivateWithControllee();
+
+  // RenderProcessHost should not be notified of foreground worker yet since
+  // there is no worker running.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(
+      0,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+
+  // Starting the worker should notify the RenderProcessHost of the foreground
+  // worker.
+  base::Optional<blink::ServiceWorkerStatusCode> status;
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
+  EXPECT_EQ(
+      1,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+
+  // Stopping the worker should notify the RenderProcessHost that the foreground
+  // worker has been removed.
+  version_->StopWorker(base::DoNothing());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(
+      0,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+}
+
+class ServiceWorkerVersionNoFetchHandlerTest : public ServiceWorkerVersionTest {
+ protected:
+  ServiceWorkerVersion::FetchHandlerExistence GetFetchHandlerExistence()
+      const override {
+    return ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST;
+  }
+};
+
+TEST_F(ServiceWorkerVersionNoFetchHandlerTest,
+       ForegroundServiceWorkerCountNotUpdated) {
+  base::test::ScopedFeatureList scoped_list;
+  scoped_list.InitAndEnableFeature(features::kServiceWorkerForegroundPriority);
+
+  // Start the worker before we have a controllee.
+  base::Optional<blink::ServiceWorkerStatusCode> status;
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
+  EXPECT_EQ(
+      0,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+
+  // Add a controllee in a different process from the service worker.
+  auto host = ActivateWithControllee();
+
+  // RenderProcessHost should not be notified if the service worker does not
+  // have a FetchEvent handler.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(
+      0,
+      helper_->mock_render_process_host()->foreground_service_worker_count());
+}
+
 TEST_F(ServiceWorkerFailToStartTest, FailingWorkerUsesNewRendererProcess) {
   base::Optional<blink::ServiceWorkerStatusCode> status;
   ServiceWorkerContextCore* context = helper_->context();
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 5f589a99..635373d87 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -117,6 +117,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/common/feature_policy/policy_value.h"
 #include "third_party/blink/public/common/frame/sandbox_flags.h"
 #include "third_party/blink/public/platform/web_input_event.h"
 #include "third_party/blink/public/platform/web_insecure_request_policy.h"
@@ -477,18 +478,18 @@
 
 // Helper function to generate a feature policy for a single feature and a list
 // of origins. (Equivalent to the declared policy "feature origin1 origin2...".)
+// TODO(loonybear): Add a test for non-bool type PolicyValue.
 blink::ParsedFeaturePolicy CreateFPHeader(
     blink::mojom::FeaturePolicyFeature feature,
     const std::vector<GURL>& origins) {
   blink::ParsedFeaturePolicy result(1);
   result[0].feature = feature;
-  result[0].matches_all_origins = false;
+  result[0].fallback_value = blink::PolicyValue(false);
+  result[0].opaque_value = blink::PolicyValue(false);
   DCHECK(!origins.empty());
   for (const GURL& origin : origins)
-    result[0].origins.push_back(url::Origin::Create(origin));
-  // We expect the parsed features to be sorted so that they can reliably be
-  // compared.
-  std::sort(result[0].origins.begin(), result[0].origins.end());
+    result[0].values.insert(std::pair<url::Origin, blink::PolicyValue>(
+        url::Origin::Create(origin), blink::PolicyValue(true)));
   return result;
 }
 
@@ -498,7 +499,8 @@
     blink::mojom::FeaturePolicyFeature feature) {
   blink::ParsedFeaturePolicy result(1);
   result[0].feature = feature;
-  result[0].matches_all_origins = true;
+  result[0].fallback_value = blink::PolicyValue(true);
+  result[0].opaque_value = blink::PolicyValue(true);
   return result;
 }
 
@@ -8912,8 +8914,8 @@
   // origin.
   const blink::ParsedFeaturePolicy initial_effective_policy =
       root->child_at(2)->effective_frame_policy().container_policy;
-  EXPECT_EQ(1UL, initial_effective_policy[0].origins.size());
-  EXPECT_FALSE(initial_effective_policy[0].origins[0].opaque());
+  EXPECT_EQ(1UL, initial_effective_policy[0].values.size());
+  EXPECT_FALSE(initial_effective_policy[0].values.begin()->first.opaque());
 
   // Set the "sandbox" attribute; pending policy should update, and should now
   // be flagged as matching the opaque origin of the frame (without containing
@@ -8925,17 +8927,17 @@
       root->child_at(2)->effective_frame_policy().container_policy;
   const blink::ParsedFeaturePolicy updated_pending_policy =
       root->child_at(2)->pending_frame_policy().container_policy;
-  EXPECT_EQ(1UL, updated_effective_policy[0].origins.size());
-  EXPECT_FALSE(updated_effective_policy[0].origins[0].opaque());
-  EXPECT_TRUE(updated_pending_policy[0].matches_opaque_src);
-  EXPECT_EQ(0UL, updated_pending_policy[0].origins.size());
+  EXPECT_EQ(1UL, updated_effective_policy[0].values.size());
+  EXPECT_FALSE(updated_effective_policy[0].values.begin()->first.opaque());
+  EXPECT_GE(updated_pending_policy[0].opaque_value, blink::PolicyValue(true));
+  EXPECT_EQ(0UL, updated_pending_policy[0].values.size());
 
   // Navigate the frame; pending policy should now be committed.
   NavigateFrameToURL(root->child_at(2), nav_url);
   const blink::ParsedFeaturePolicy final_effective_policy =
       root->child_at(2)->effective_frame_policy().container_policy;
-  EXPECT_TRUE(final_effective_policy[0].matches_opaque_src);
-  EXPECT_EQ(0UL, final_effective_policy[0].origins.size());
+  EXPECT_GE(final_effective_policy[0].opaque_value, blink::PolicyValue(true));
+  EXPECT_EQ(0UL, final_effective_policy[0].values.size());
 }
 
 // Test that creating a new remote frame at the same origin as its parent
@@ -14109,6 +14111,43 @@
   EXPECT_FALSE(did_start_navigation_observer.observed());
 }
 
+// An history navigation from the renderer process is received while the
+// RenderFrameHost is pending deletion.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+                       HistoryNavigationWhilePendingDeletion) {
+  GURL url_ab(embedded_test_server()->GetURL(
+      "a.com", "/cross_site_iframe_factory.html?a(b)"));
+  GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html"));
+
+  EXPECT_TRUE(NavigateToURL(shell(), url_ab));
+  RenderFrameHostImpl* rfh_a = web_contents()->GetMainFrame();
+  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();
+  NavigateFrameToURL(rfh_b->frame_tree_node(), url_c);
+  RenderFrameHostImpl* rfh_c = rfh_a->child_at(0)->current_frame_host();
+
+  // Frame C has a unload handler. The browser process needs to wait before
+  // deleting it.
+  EXPECT_TRUE(ExecJs(rfh_c, "onunload=function(){}"));
+
+  RenderFrameDeletedObserver deleted_observer(rfh_c);
+  TestNavigationManager navigation_observer(web_contents(), url_ab);
+
+  // History navigation on C.
+  ExecuteScriptAsync(rfh_c, "history.back();");
+
+  // Simulate A deleting C.
+  // It starts before receiving the history navigation. The detach ACK is
+  // received after.
+  rfh_c->DetachFromProxy();
+  deleted_observer.WaitUntilDeleted();
+
+  // The NavigationController won't be able to find the subframe to navigate
+  // since it was just detached, so it should fall back to navigating the main
+  // frame
+  navigation_observer.WaitForNavigationFinished();
+  EXPECT_TRUE(navigation_observer.was_successful());
+}
+
 // This test verifies that when scrolling an OOPIF in a pinched-zoomed page,
 // that the scroll-delta matches the distance between TouchStart/End as seen
 // by the oopif, i.e. the oopif content 'sticks' to the finger during scrolling.
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc
index 5e1c913..25c05c1 100644
--- a/content/browser/utility_process_host.cc
+++ b/content/browser/utility_process_host.cc
@@ -376,6 +376,7 @@
       switches::kV,
       switches::kVModule,
 #if defined(OS_ANDROID)
+      switches::kEnableReachedCodeProfiler,
       switches::kOrderfileMemoryOptimization,
 #endif
       // These flags are used by the audio service:
diff --git a/content/common/content_param_traits.cc b/content/common/content_param_traits.cc
index 78b7421..9296444 100644
--- a/content/common/content_param_traits.cc
+++ b/content/common/content_param_traits.cc
@@ -17,6 +17,7 @@
 #include "ipc/ipc_mojo_message_helper.h"
 #include "ipc/ipc_mojo_param_traits.h"
 #include "net/base/ip_endpoint.h"
+#include "third_party/blink/public/common/feature_policy/feature_policy.h"
 #include "third_party/blink/public/common/messaging/message_port_channel.h"
 #include "third_party/blink/public/common/messaging/transferable_message.h"
 #include "third_party/blink/public/mojom/messaging/transferable_message.mojom.h"
@@ -90,6 +91,44 @@
 void ParamTraits<blink::MessagePortChannel>::Log(const param_type& p,
                                                  std::string* l) {}
 
+void ParamTraits<blink::PolicyValue>::Write(base::Pickle* m,
+                                            const param_type& p) {
+  blink::mojom::PolicyValueType type = p.Type();
+  WriteParam(m, static_cast<int>(type));
+  switch (type) {
+    case blink::mojom::PolicyValueType::kBool:
+      WriteParam(m, p.BoolValue());
+      break;
+    case blink::mojom::PolicyValueType::kNull:
+      break;
+  }
+}
+
+bool ParamTraits<blink::PolicyValue>::Read(const base::Pickle* m,
+                                           base::PickleIterator* iter,
+                                           param_type* r) {
+  int int_type;
+  if (!ReadParam(m, iter, &int_type))
+    return false;
+  blink::mojom::PolicyValueType type =
+      static_cast<blink::mojom::PolicyValueType>(int_type);
+  switch (type) {
+    case blink::mojom::PolicyValueType::kBool: {
+      bool b;
+      if (!ReadParam(m, iter, &b))
+        return false;
+      r->SetBoolValue(b);
+      break;
+    }
+    case blink::mojom::PolicyValueType::kNull:
+      break;
+  }
+  return true;
+}
+
+void ParamTraits<blink::PolicyValue>::Log(const param_type& p, std::string* l) {
+}
+
 void ParamTraits<ui::AXMode>::Write(base::Pickle* m, const param_type& p) {
   IPC::WriteParam(m, p.mode());
 }
diff --git a/content/common/content_param_traits.h b/content/common/content_param_traits.h
index 565d97c..38d041c 100644
--- a/content/common/content_param_traits.h
+++ b/content/common/content_param_traits.h
@@ -22,6 +22,7 @@
 #include "ui/accessibility/ax_mode.h"
 
 namespace blink {
+class PolicyValue;
 class MessagePortChannel;
 struct TransferableMessage;
 }
@@ -70,7 +71,18 @@
 struct CONTENT_EXPORT ParamTraits<blink::MessagePortChannel> {
   typedef blink::MessagePortChannel param_type;
   static void Write(base::Pickle* m, const param_type& p);
-  static bool Read(const base::Pickle* m, base::PickleIterator* iter,
+  static bool Read(const base::Pickle* m,
+                   base::PickleIterator* iter,
+                   param_type* r);
+  static void Log(const param_type& p, std::string* l);
+};
+
+template <>
+struct CONTENT_EXPORT ParamTraits<blink::PolicyValue> {
+  typedef blink::PolicyValue param_type;
+  static void Write(base::Pickle* m, const param_type& p);
+  static bool Read(const base::Pickle* m,
+                   base::PickleIterator* iter,
                    param_type* r);
   static void Log(const param_type& p, std::string* l);
 };
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index a0619cfaa..b48fee6 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -528,9 +528,9 @@
 
 IPC_STRUCT_TRAITS_BEGIN(blink::ParsedFeaturePolicyDeclaration)
   IPC_STRUCT_TRAITS_MEMBER(feature)
-  IPC_STRUCT_TRAITS_MEMBER(matches_all_origins)
-  IPC_STRUCT_TRAITS_MEMBER(matches_opaque_src)
-  IPC_STRUCT_TRAITS_MEMBER(origins)
+  IPC_STRUCT_TRAITS_MEMBER(values)
+  IPC_STRUCT_TRAITS_MEMBER(fallback_value)
+  IPC_STRUCT_TRAITS_MEMBER(opaque_value)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(content::FrameReplicationState)
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
index 4c88d24..6cc28a1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
@@ -419,9 +419,9 @@
     }
 
     @CalledByNative
-    private void setPriority(int pid, boolean visible, boolean hasMediaStream, long frameDepth,
-            boolean intersectsViewport, boolean boostForPendingViews,
-            @ChildProcessImportance int importance) {
+    private void setPriority(int pid, boolean visible, boolean hasMediaStream,
+            boolean hasForegroundServiceWorker, long frameDepth, boolean intersectsViewport,
+            boolean boostForPendingViews, @ChildProcessImportance int importance) {
         assert LauncherThread.runningOnLauncherThread();
         assert mLauncher.getPid() == pid;
         if (getByPid(pid) == null) {
@@ -438,6 +438,9 @@
         boolean mediaRendererHasModerate = ContentFeatureList.isEnabled(
                 ContentFeatureList.BACKGROUND_MEDIA_RENDERER_HAS_MODERATE_BINDING);
 
+        boolean serviceWorkerForegroundPriority =
+                ContentFeatureList.isEnabled(ContentFeatureList.SERVICE_WORKER_FOREGROUND_PRIORITY);
+
         @ChildProcessImportance
         int newEffectiveImportance;
         if ((visible && frameDepth == 0) || importance == ChildProcessImportance.IMPORTANT
@@ -445,7 +448,8 @@
             newEffectiveImportance = ChildProcessImportance.IMPORTANT;
         } else if ((visible && frameDepth > 0 && intersectsViewport) || boostForPendingViews
                 || importance == ChildProcessImportance.MODERATE
-                || (hasMediaStream && mediaRendererHasModerate)) {
+                || (hasMediaStream && mediaRendererHasModerate)
+                || (hasForegroundServiceWorker && serviceWorkerForegroundPriority)) {
             newEffectiveImportance = ChildProcessImportance.MODERATE;
         } else {
             newEffectiveImportance = ChildProcessImportance.NORMAL;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentFeatureList.java b/content/public/android/java/src/org/chromium/content/browser/ContentFeatureList.java
index 2a0060a9..432934c 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentFeatureList.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentFeatureList.java
@@ -36,5 +36,8 @@
     public static final String BACKGROUND_MEDIA_RENDERER_HAS_MODERATE_BINDING =
             "BackgroundMediaRendererHasModerateBinding";
 
+    public static final String SERVICE_WORKER_FOREGROUND_PRIORITY =
+            "ServiceWorkerForegroundPriority";
+
     private static native boolean nativeIsEnabled(String featureName);
 }
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h
index 5cc4b2b..1eeb9141 100644
--- a/content/public/browser/render_frame_host.h
+++ b/content/public/browser/render_frame_host.h
@@ -19,6 +19,7 @@
 #include "ipc/ipc_listener.h"
 #include "ipc/ipc_sender.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
+#include "third_party/blink/public/common/feature_policy/feature_policy.h"
 #include "third_party/blink/public/common/frame/sandbox_flags.h"
 #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-forward.h"
 #include "third_party/blink/public/platform/web_sudden_termination_disabler_type.h"
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h
index e82f78a0..4f0b36f 100644
--- a/content/public/browser/render_process_host.h
+++ b/content/public/browser/render_process_host.h
@@ -166,6 +166,12 @@
   virtual void OnMediaStreamAdded() = 0;
   virtual void OnMediaStreamRemoved() = 0;
 
+  // Called when a service worker is executing in the process and may need
+  // to respond to events from other processes in a timely manner.  This is
+  // used to determine if the process should be backgrounded or not.
+  virtual void OnForegroundServiceWorkerAdded() = 0;
+  virtual void OnForegroundServiceWorkerRemoved() = 0;
+
   // Indicates whether the current RenderProcessHost is exclusively hosting
   // guest RenderFrames. Not all guest RenderFrames are created equal.  A guest,
   // as indicated by BrowserPluginGuest::IsGuest, may coexist with other
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 1dae5f3a..2719764e 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -408,6 +408,11 @@
 const base::Feature kSecMetadata{"SecMetadata",
                                  base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Keep processes with service workers controlling clients from other
+// processes at foreground priority. (crbug.com/928904)
+const base::Feature kServiceWorkerForegroundPriority{
+    "ServiceWorkerForegroundPriority", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables long running message dispatch for service workers.
 // This is a temporary addition only to be used for the Android Messages
 // integration with ChromeOS (http://crbug.com/823256).
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 5778c77a..499aaef2 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -98,6 +98,7 @@
 CONTENT_EXPORT extern const base::Feature
     kSendBeaconThrowForBlobWithNonSimpleType;
 CONTENT_EXPORT extern const base::Feature kSecMetadata;
+CONTENT_EXPORT extern const base::Feature kServiceWorkerForegroundPriority;
 CONTENT_EXPORT extern const base::Feature kServiceWorkerLongRunningMessage;
 CONTENT_EXPORT extern const base::Feature kServiceWorkerPaymentApps;
 CONTENT_EXPORT extern const base::Feature kSharedArrayBuffer;
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc
index d1429ce9..2843986 100644
--- a/content/public/test/mock_render_process_host.cc
+++ b/content/public/test/mock_render_process_host.cc
@@ -57,6 +57,7 @@
       is_process_backgrounded_(false),
       is_unused_(true),
       keep_alive_ref_count_(0),
+      foreground_service_worker_count_(0),
       child_identity_(
           mojom::kRendererServiceName,
           BrowserContext::GetServiceInstanceGroupFor(browser_context),
@@ -192,6 +193,15 @@
 
 void MockRenderProcessHost::OnMediaStreamRemoved() {}
 
+void MockRenderProcessHost::OnForegroundServiceWorkerAdded() {
+  foreground_service_worker_count_ += 1;
+}
+
+void MockRenderProcessHost::OnForegroundServiceWorkerRemoved() {
+  DCHECK_GT(foreground_service_worker_count_, 0);
+  foreground_service_worker_count_ -= 1;
+}
+
 StoragePartition* MockRenderProcessHost::GetStoragePartition() {
   return BrowserContext::GetDefaultStoragePartition(browser_context_);
 }
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h
index 8a5f877..57bce318 100644
--- a/content/public/test/mock_render_process_host.h
+++ b/content/public/test/mock_render_process_host.h
@@ -86,6 +86,8 @@
   GetRendererAudioOutputStreamFactoryContext() override;
   void OnMediaStreamAdded() override;
   void OnMediaStreamRemoved() override;
+  void OnForegroundServiceWorkerAdded() override;
+  void OnForegroundServiceWorkerRemoved() override;
   StoragePartition* GetStoragePartition() override;
   virtual void AddWord(const base::string16& word);
   bool Shutdown(int exit_code) override;
@@ -200,6 +202,10 @@
     return is_renderer_locked_to_site_;
   }
 
+  int foreground_service_worker_count() const {
+    return foreground_service_worker_count_;
+  }
+
  private:
   // Stores IPC messages that would have been sent to the renderer.
   IPC::TestSink sink_;
@@ -221,6 +227,7 @@
   bool is_unused_;
   base::Process process;
   int keep_alive_ref_count_;
+  int foreground_service_worker_count_;
   std::unique_ptr<mojo::AssociatedInterfacePtr<mojom::Renderer>>
       renderer_interface_;
   std::map<std::string, InterfaceBinder> binder_overrides_;
diff --git a/content/shell/tools/breakpad_integration_test.py b/content/shell/tools/breakpad_integration_test.py
index a378c313..8822edc 100755
--- a/content/shell/tools/breakpad_integration_test.py
+++ b/content/shell/tools/breakpad_integration_test.py
@@ -25,17 +25,64 @@
 BREAKPAD_TOOLS_DIR = os.path.join(
   os.path.dirname(__file__), '..', '..', '..',
   'components', 'crash', 'content', 'tools')
+ANDROID_CRASH_DIR = '/data/local/tmp/crashes'
 
-def run_test(options, crash_dir, symbols_dir, additional_arguments = []):
+def build_is_android(build_dir):
+  return os.path.isfile(os.path.join(build_dir, 'bin', 'content_shell_apk'))
+
+def android_crash_dir_exists():
+  proc = subprocess.Popen(['adb', 'shell', 'ls', ANDROID_CRASH_DIR],
+                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+  [stdout, stderr] = proc.communicate()
+  not_found = 'No such file or directory'
+  return not_found not in stdout and not_found not in stderr
+
+def get_android_dump(crash_dir):
   global failure
 
-  print "# Run content_shell and make it crash."
-  cmd = [options.binary,
-         '--run-web-tests',
-         'chrome://crash',
-         '--enable-crash-reporter',
-         '--crash-dumps-dir=%s' % crash_dir]
-  cmd += additional_arguments
+  pending = ANDROID_CRASH_DIR + '/pending/'
+
+  for attempts in range(5):
+    proc = subprocess.Popen(
+        ['adb', 'shell', 'ls', pending + '*.dmp'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+    dumps = [f for f in map(str.strip, proc.communicate()[0].split('\n'))
+             if f.endswith('.dmp')]
+    if len(dumps) > 0:
+      break
+    # Crashpad may still be writing the dump. Sleep and try again.
+    time.sleep(1)
+
+  if len(dumps) != 1:
+    failure = 'Expected 1 crash dump, found %d.' % len(dumps)
+    print dumps
+    raise Exception(failure)
+
+  subprocess.check_call(['adb', 'pull', dumps[0], crash_dir])
+  subprocess.check_call(['adb', 'shell', 'rm', pending + '*'])
+
+  return os.path.join(crash_dir, os.path.basename(dumps[0]))
+
+def run_test(options, crash_dir, symbols_dir, platform,
+             additional_arguments = []):
+  global failure
+
+  print '# Run content_shell and make it crash.'
+  if platform == 'android':
+    cmd = [os.path.join(options.build_dir, 'bin', 'content_shell_apk'),
+           'launch',
+           'chrome://crash',
+           '--args=--enable-crash-reporter --crash-dumps-dir=%s ' %
+           ANDROID_CRASH_DIR + ' '.join(additional_arguments)]
+  else:
+    cmd = [options.binary,
+           '--run-web-tests',
+           'chrome://crash',
+           '--enable-crash-reporter',
+           '--crash-dumps-dir=%s' % crash_dir]
+    cmd += additional_arguments
+
   if options.verbose:
     print ' '.join(cmd)
   failure = 'Failed to run content_shell.'
@@ -47,21 +94,25 @@
     with tempfile.TemporaryFile() as tmpfile:
       subprocess.check_call(cmd, stdout=tmpfile, stderr=tmpfile)
 
-  print "# Retrieve crash dump."
-  dmp_dir = crash_dir
-  # TODO(crbug.com/782923): This test should not reach directly into the
-  # Crashpad database, but instead should use crashpad_database_util.
-  if sys.platform == 'darwin':
-    dmp_dir = os.path.join(dmp_dir, 'pending')
-  elif sys.platform == 'win32':
-    dmp_dir = os.path.join(dmp_dir, 'reports')
-  dmp_files = glob.glob(os.path.join(dmp_dir, '*.dmp'))
-  failure = 'Expected 1 crash dump, found %d.' % len(dmp_files)
-  if len(dmp_files) != 1:
-    raise Exception(failure)
-  dmp_file = dmp_files[0]
+  print '# Retrieve crash dump.'
+  if platform == 'android':
+    dmp_file = get_android_dump(crash_dir)
+  else:
+    dmp_dir = crash_dir
+    # TODO(crbug.com/782923): This test should not reach directly into the
+    # Crashpad database, but instead should use crashpad_database_util.
+    if platform == 'darwin':
+      dmp_dir = os.path.join(dmp_dir, 'pending')
+    elif platform == 'win32':
+      dmp_dir = os.path.join(dmp_dir, 'reports')
 
-  if sys.platform not in ('darwin', 'win32'):
+    dmp_files = glob.glob(os.path.join(dmp_dir, '*.dmp'))
+    failure = 'Expected 1 crash dump, found %d.' % len(dmp_files)
+    if len(dmp_files) != 1:
+      raise Exception(failure)
+    dmp_file = dmp_files[0]
+
+  if platform not in ('darwin', 'win32', 'android'):
     minidump = os.path.join(crash_dir, 'minidump')
     dmp_to_minidump = os.path.join(BREAKPAD_TOOLS_DIR, 'dmp2minidump.py')
     cmd = [dmp_to_minidump, dmp_file, minidump]
@@ -72,8 +123,8 @@
   else:
     minidump = dmp_file
 
-  print "# Symbolize crash dump."
-  if sys.platform == 'win32':
+  print '# Symbolize crash dump.'
+  if platform == 'win32':
     cdb_exe = os.path.join(options.build_dir, 'cdb', 'cdb.exe')
     cmd = [cdb_exe, '-y', options.build_dir, '-c', '.lines;.excr;k30;q',
            '-z', dmp_file]
@@ -137,19 +188,30 @@
   (options, _) = parser.parse_args()
 
   if not options.build_dir:
-    print "Required option --build-dir missing."
+    print 'Required option --build-dir missing.'
     return 1
 
   if not options.binary:
-    print "Required option --binary missing."
+    print 'Required option --binary missing.'
     return 1
 
   if not os.access(options.binary, os.X_OK):
-    print "Cannot find %s." % options.binary
+    print 'Cannot find %s.' % options.binary
     return 1
 
   failure = ''
 
+  if build_is_android(options.build_dir):
+    platform = 'android'
+    if android_crash_dir_exists():
+      print 'Android crash dir exists %s' % ANDROID_CRASH_DIR
+      return 1
+
+    subprocess.check_call(['adb', 'shell', 'mkdir', ANDROID_CRASH_DIR])
+
+  else:
+    platform = sys.platform
+
   # Create a temporary directory to store the crash dumps and symbols in.
   crash_dir = tempfile.mkdtemp()
   symbols_dir = os.path.join(crash_dir, 'symbols')
@@ -157,8 +219,8 @@
   crash_service = None
 
   try:
-    if sys.platform != 'win32':
-      print "# Generate symbols."
+    if platform != 'win32':
+      print '# Generate symbols.'
       bins = [options.binary]
       if options.additional_binary:
         bins.append(options.additional_binary)
@@ -176,15 +238,15 @@
         failure = 'Failed to run generate_breakpad_symbols.py.'
         subprocess.check_call(cmd)
 
-    print "# Running test without trap handler."
-    run_test(options, crash_dir, symbols_dir)
-    print "# Running test with trap handler."
-    run_test(options, crash_dir, symbols_dir,
+    print '# Running test without trap handler.'
+    run_test(options, crash_dir, symbols_dir, platform)
+    print '# Running test with trap handler.'
+    run_test(options, crash_dir, symbols_dir, platform,
              additional_arguments =
                ['--enable-features=WebAssemblyTrapHandler'])
 
   except:
-    print "FAIL: %s" % failure
+    print 'FAIL: %s' % failure
     if options.json:
       with open(options.json, 'w') as json_file:
         json.dump([failure], json_file)
@@ -192,7 +254,7 @@
     return 1
 
   else:
-    print "PASS: Breakpad integration test ran successfully."
+    print 'PASS: Breakpad integration test ran successfully.'
     if options.json:
       with open(options.json, 'w') as json_file:
         json.dump([], json_file)
@@ -206,6 +268,11 @@
       shutil.rmtree(crash_dir)
     except:
       print 'Failed to delete temp directory "%s".' % crash_dir
+    if platform == 'android':
+      try:
+        subprocess.check_call(['adb', 'shell', 'rm', '-rf', ANDROID_CRASH_DIR])
+      except:
+        print 'Failed to delete android crash dir %s' % ANDROID_CRASH_DIR
 
 
 if '__main__' == __name__:
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index 1be633a..883f2bf8 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -202,13 +202,18 @@
   OnSwapOutACK();
 }
 
+// TODO(loonybear): Add a test for non-bool type PolicyValue.
 void TestRenderFrameHost::SimulateFeaturePolicyHeader(
     blink::mojom::FeaturePolicyFeature feature,
     const std::vector<url::Origin>& whitelist) {
   blink::ParsedFeaturePolicy header(1);
   header[0].feature = feature;
-  header[0].matches_all_origins = false;
-  header[0].origins = whitelist;
+  header[0].fallback_value = blink::PolicyValue(false);
+  header[0].opaque_value = blink::PolicyValue(false);
+  for (const auto& origin : whitelist) {
+    header[0].values.insert(std::pair<url::Origin, blink::PolicyValue>(
+        origin, blink::PolicyValue(true)));
+  }
   DidSetFramePolicyHeaders(blink::WebSandboxFlags::kNone, header);
 }
 
diff --git a/docs/README.md b/docs/README.md
index 9939e5c6..841aa7f 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -163,7 +163,7 @@
     Running web tests by hand.
 *   [Web Platform Tests](testing/web_platform_tests.md) - Shared tests across
     browser vendors
-*   [Using Breakpad with `content_shell`](testing/using_breakpad_with_content_shell.md) -
+*   [Using Crashpad with `content_shell`](testing/using_crashpad_with_content_shell.md) -
     Capture stack traces on layout test crashes without an attached debugger
 *   [Test Descriptions](test_descriptions.md) - Unit test targets that can be
     built, with associated desciptions.
diff --git a/docs/android_test_instructions.md b/docs/android_test_instructions.md
index 26ed2c7b..6d4a8fe 100644
--- a/docs/android_test_instructions.md
+++ b/docs/android_test_instructions.md
@@ -243,13 +243,9 @@
 out/Release/bin/run_chrome_public_test_apk [-vv]
 ```
 
-AndroidWebView tests:
+Android WebView tests:
 
-```shell
-ninja -C out/Release webview_instrumentation_apk
-ninja -C out/Release webview_instrumentation_test_apk
-out/Release/bin/run_webview_instrumentation_test_apk [-vv]
-```
+See [WebView's instructions](/android_webview/docs/test-instructions.md).
 
 In order to run a subset of tests, use -f to filter based on test class/method
 or -A/-E to filter using annotations.
diff --git a/docs/testing/using_breakpad_with_content_shell.md b/docs/testing/using_crashpad_with_content_shell.md
similarity index 78%
rename from docs/testing/using_breakpad_with_content_shell.md
rename to docs/testing/using_crashpad_with_content_shell.md
index 4435ddf..a582dc7 100644
--- a/docs/testing/using_breakpad_with_content_shell.md
+++ b/docs/testing/using_crashpad_with_content_shell.md
@@ -1,8 +1,9 @@
-# Using breakpad with content shell
+# Using crashpad with content shell
 
 When running web tests, it is possible to use
-[breakpad](../../third_party/breakpad/) to capture stack traces on crashes while
-running without a debugger attached and with the sandbox enabled.
+[crashpad](../third_party/crashpad/)/[breakpad](../../third_party/breakpad/) to
+capture stack traces on crashes while running without a debugger attached and
+with the sandbox enabled.
 
 ## Setup
 
@@ -21,6 +22,12 @@
 building.
 ***
 
+*** note
+**Android:** Add `force_local_build_id = true` to your [gn build
+arguments](https://gn.googlesource.com/gn/+/master/docs/quick_start.md) before
+building.
+***
+
 Then, create a directory where the crash dumps will be stored:
 
 * Linux/Mac:
@@ -36,9 +43,9 @@
   mkdir %TEMP%\crashes
   ```
 
-## Running content shell with breakpad
+## Running content shell with crashpad
 
-Breakpad can be enabled by passing `--enable-crash-reporter` and
+Crashpad can be enabled by passing `--enable-crash-reporter` and
 `--crash-dumps-dir` to content shell:
 
 * Linux:
@@ -58,10 +65,9 @@
   ```
 * Android:
   ```bash
-  build/android/adb_install_apk.py out/Default/apks/ContentShell.apk
-  build/android/adb_content_shell_command_line --enable-crash-reporter \
-      --crash-dumps-dir=/data/local/tmp/crashes chrome://crash
-  build/android/adb_run_content_shell
+  out/Default/bin/content_shell_apk install
+  out/Default/bin/content_shell_apk launch chrome://crash
+  --args="--enable-crash-reporter --crash-dumps-dir=/data/local/tmp/crashes"
   ```
 
 ## Retrieving the crash dump
@@ -75,8 +81,7 @@
   ```
 * Android:
   ```bash
-  adb pull $(adb shell ls /data/local/tmp/crashes/*) /tmp/chromium-renderer-minidump.dmp
-  components/breakpad/tools/dmp2minidump /tmp/chromium-renderer-minidump.dmp /tmp/minidump
+  adb pull $(adb shell ls /data/local/tmp/crashes/pending/*.dmp) /tmp/chromium-renderer-minidump.dmp
   ```
 
 ## Symbolizing the crash dump
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
index ded86db..abbac459 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
@@ -32,6 +32,7 @@
 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
 #include "extensions/browser/guest_view/mime_handler_view/test_mime_handler_view_guest.h"
 #include "extensions/browser/process_manager.h"
+#include "extensions/common/guest_view/extensions_guest_view_messages.h"
 #include "extensions/test/result_catcher.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -91,6 +92,10 @@
     return manager;
   }
 
+  content::WebContents* GetEmbedderWebContents() {
+    return browser()->tab_strip_model()->GetWebContentsAt(0);
+  }
+
   MimeHandlerViewGuest* GetLastGuestView() const {
     return MimeHandlerViewGuest::FromWebContents(
                GetGuestViewManager()->GetLastGuestCreated())
@@ -117,6 +122,7 @@
     ASSERT_TRUE(extension);
 
     extensions::ResultCatcher catcher;
+
     ui_test_utils::NavigateToURL(browser(), url);
 
     if (!catcher.GetNextResult())
@@ -267,6 +273,35 @@
   RunTestWithUrl(test_url);
 }
 
+// This test verifies that removing embedder RenderFrame will not crash the
+// renderer (for context see https://crbug.com/930803).
+IN_PROC_BROWSER_TEST_P(MimeHandlerViewCrossProcessTest,
+                       EmbedderFrameRemovedNoCrash) {
+  if (!is_cross_process_mode()) {
+    // The associated crash is due to handling an IPC which is only used on the
+    // frame-based MimeHandlerView.
+  }
+  RunTest("test_iframe.html");
+  auto* guest_view = GuestViewBase::FromWebContents(
+      GetGuestViewManager()->WaitForSingleGuestCreated());
+  ASSERT_TRUE(guest_view);
+  int32_t element_instance_id = guest_view->element_instance_id();
+  auto* embedder_web_contents = GetEmbedderWebContents();
+  auto* child_frame =
+      content::ChildFrameAt(embedder_web_contents->GetMainFrame(), 0);
+  content::RenderFrameDeletedObserver render_frame_observer(child_frame);
+  ASSERT_TRUE(
+      content::ExecJs(embedder_web_contents,
+                      "document.querySelector('iframe').outerHTML = ''"));
+  render_frame_observer.WaitUntilDeleted();
+  // Send the IPC. During destruction MHVFC would cause a UaF since it was not
+  // removed from the global map.
+  embedder_web_contents->GetMainFrame()->Send(
+      new ExtensionsGuestViewMsg_DestroyFrameContainer(element_instance_id));
+  // Running the following JS code fails if the renderer has crashed.
+  ASSERT_TRUE(content::ExecJs(embedder_web_contents, "window.name = 'foo'"));
+}
+
 // TODO(ekaramad): Somehow canceling a first dialog in a setup similar to the
 // test below pops up another dialog. This is likely due to the navigation to
 // about:blank from both the browser side and the embedder side in the method
@@ -464,12 +499,6 @@
   ~MimeHandlerViewBrowserPluginSpecificTest() override {}
 
  protected:
-  // None of these test create new tabs, so the embedder should be the first
-  // tab.
-  content::WebContents* GetEmbedderWebContents() {
-    return browser()->tab_strip_model()->GetWebContentsAt(0);
-  }
-
   DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewBrowserPluginSpecificTest);
 };
 
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_base.h b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_base.h
index a47a76d..f7e7d1a 100644
--- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_base.h
+++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_base.h
@@ -83,6 +83,9 @@
   void EmbedderRenderFrameWillBeGone();
   v8::Local<v8::Object> GetScriptableObject(v8::Isolate* isolate);
 
+  // Returns the frame which is embedding the corresponding plugin element.
+  content::RenderFrame* GetEmbedderRenderFrame() const;
+
   bool guest_created() const { return guest_created_; }
 
   // Used when network service is enabled:
@@ -105,9 +108,6 @@
  private:
   class PluginResourceThrottle;
 
-  // Returns the frame which is embedding the corresponding plugin element.
-  content::RenderFrame* GetEmbedderRenderFrame() const;
-
   // Called for embedded plugins when network service is enabled. This is called
   // by the URLLoaderThrottle which intercepts the resource load, which is then
   // sent to the browser to be handed off to the plugin.
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.cc b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.cc
index a550b9b..aafb1df 100644
--- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.cc
+++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.cc
@@ -10,6 +10,7 @@
 #include "base/pickle.h"
 #include "content/public/common/webplugininfo.h"
 #include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_frame_observer.h"
 #include "third_party/blink/public/web/web_document.h"
 #include "third_party/blink/public/web/web_frame.h"
 #include "third_party/blink/public/web/web_local_frame.h"
@@ -27,6 +28,32 @@
 
 }  // namespace
 
+class MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver
+    : public content::RenderFrameObserver {
+ public:
+  RenderFrameLifetimeObserver(content::RenderFrame* render_frame,
+                              MimeHandlerViewFrameContainer* container);
+  ~RenderFrameLifetimeObserver() override;
+
+  // content:RenderFrameObserver override.
+  void OnDestruct() final;
+
+ private:
+  MimeHandlerViewFrameContainer* const container_;
+};
+
+MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver::
+    RenderFrameLifetimeObserver(content::RenderFrame* render_frame,
+                                MimeHandlerViewFrameContainer* container)
+    : content::RenderFrameObserver(render_frame), container_(container) {}
+
+MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver::
+    ~RenderFrameLifetimeObserver() {}
+
+void MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver::OnDestruct() {
+  container_->OnDestroyFrameContainer(container_->element_instance_id_);
+}
+
 // static
 bool MimeHandlerViewFrameContainer::Create(
     const blink::WebElement& plugin_element,
@@ -62,7 +89,9 @@
                                    mime_type,
                                    resource_url),
       plugin_element_(plugin_element),
-      element_instance_id_(element_instance_id) {
+      element_instance_id_(element_instance_id),
+      render_frame_lifetime_observer_(
+          new RenderFrameLifetimeObserver(GetEmbedderRenderFrame(), this)) {
   is_embedded_ = IsEmbedded();
   if (is_embedded_) {
     SendResourceRequest();
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.h b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.h
index fd1ac90..32e52ae1 100644
--- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.h
+++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_frame_container.h
@@ -33,6 +33,9 @@
                      int32_t element_instance_id);
 
  private:
+  class RenderFrameLifetimeObserver;
+  friend class RenderFrameLifetimeObserver;
+
   MimeHandlerViewFrameContainer(const blink::WebElement& plugin_element,
                                 const GURL& resource_url,
                                 const std::string& mime_type,
@@ -66,6 +69,7 @@
 
   blink::WebElement plugin_element_;
   const int32_t element_instance_id_;
+  std::unique_ptr<RenderFrameLifetimeObserver> render_frame_lifetime_observer_;
 
   DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewFrameContainer);
 };
diff --git a/google_apis/gaia/oauth2_access_token_fetcher_impl.cc b/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
index 53fd62f..036d84d 100644
--- a/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
+++ b/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
@@ -208,7 +208,8 @@
 
   bool net_failure = false;
   int histogram_value;
-  if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) {
+  if (url_loader_->NetError() == net::OK && url_loader_->ResponseInfo() &&
+      url_loader_->ResponseInfo()->headers) {
     // Note that the SimpleURLLoader reports net::ERR_FAILED for HTTP codes
     // other than 200s.
     histogram_value = url_loader_->ResponseInfo()->headers->response_code();
@@ -227,6 +228,13 @@
   switch (response_code) {
     case net::HTTP_OK:
       break;
+    case net::HTTP_PROXY_AUTHENTICATION_REQUIRED:
+      NOTREACHED() << "HTTP 407 should be treated as a network error.";
+      // If this ever happens in production, we treat it as a temporary error as
+      // it is similar to a network error.
+      OnGetTokenFailure(
+          GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
+      return;
     case net::HTTP_FORBIDDEN:
       // HTTP_FORBIDDEN (403) is treated as temporary error, because it may be
       // '403 Rate Limit Exeeded.'
diff --git a/google_apis/gaia/oauth2_access_token_fetcher_impl_unittest.cc b/google_apis/gaia/oauth2_access_token_fetcher_impl_unittest.cc
index 000dd25..0acdc97 100644
--- a/google_apis/gaia/oauth2_access_token_fetcher_impl_unittest.cc
+++ b/google_apis/gaia/oauth2_access_token_fetcher_impl_unittest.cc
@@ -20,6 +20,7 @@
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/network/test/test_url_loader_factory.h"
+#include "services/network/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -103,6 +104,21 @@
                 Intercept(resourceRequestUrlEquals(url)));
   }
 
+  void SetupProxyError() {
+    GURL url(GaiaUrls::GetInstance()->oauth2_token_url());
+    url_loader_factory_.AddResponse(
+        url,
+        network::CreateResourceResponseHead(
+            net::HTTP_PROXY_AUTHENTICATION_REQUIRED),
+        std::string(),
+        network::URLLoaderCompletionStatus(net::ERR_TUNNEL_CONNECTION_FAILED),
+        network::TestURLLoaderFactory::Redirects(),
+        network::TestURLLoaderFactory::kSendHeadersOnNetworkError);
+
+    EXPECT_CALL(url_loader_factory_interceptor_,
+                Intercept(resourceRequestUrlEquals(url)));
+  }
+
  protected:
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   MockOAuth2AccessTokenConsumer consumer_;
@@ -128,6 +144,18 @@
   base::RunLoop().RunUntilIdle();
 }
 
+// Regression test for https://crbug.com/914672
+TEST_F(OAuth2AccessTokenFetcherImplTest, ProxyFailure) {
+  GoogleServiceAuthError expected_error =
+      GoogleServiceAuthError::FromConnectionError(
+          net::ERR_TUNNEL_CONNECTION_FAILED);
+  ASSERT_TRUE(expected_error.IsTransientError());
+  SetupProxyError();
+  EXPECT_CALL(consumer_, OnGetTokenFailure(expected_error)).Times(1);
+  fetcher_.Start("client_id", "client_secret", ScopeList());
+  base::RunLoop().RunUntilIdle();
+}
+
 TEST_F(OAuth2AccessTokenFetcherImplTest, Success) {
   SetupGetAccessToken(net::OK, net::HTTP_OK, kValidTokenResponse);
   EXPECT_CALL(consumer_, OnGetTokenSuccess(_)).Times(1);
diff --git a/gpu/ipc/host/shader_disk_cache.cc b/gpu/ipc/host/shader_disk_cache.cc
index 339c8ce6..21762df6 100644
--- a/gpu/ipc/host/shader_disk_cache.cc
+++ b/gpu/ipc/host/shader_disk_cache.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/macros.h"
+#include "base/memory/ref_counted.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/system/sys_info.h"
 #include "base/threading/thread_checker.h"
@@ -146,19 +147,20 @@
 };
 
 // When the cache is asked to open an entry an Entry** is passed to it. The
-// underying Entry* must stay alive for the duration of the call, so it is
-// owned by the callback. If the underlying state machine is deleted before
-// the callback runs, close the entry.
+// underlying Entry* must stay alive for the duration of the call, so it is ref
+// counted. If the underlying state machine is deleted before the callback runs,
+// close the entry.
 template <typename T>
-void OnEntryOpenComplete(base::WeakPtr<T> state_machine,
-                         std::unique_ptr<disk_cache::Entry*> entry,
-                         int rv) {
+void OnEntryOpenComplete(
+    base::WeakPtr<T> state_machine,
+    scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry_ptr,
+    int rv) {
   if (!state_machine) {
     if (rv == net::OK)
-      (*entry)->Close();
+      entry_ptr->data->Close();
     return;
   }
-  state_machine->set_entry(*entry);
+  state_machine->set_entry(entry_ptr->data);
   state_machine->OnOpComplete(rv);
 }
 
@@ -186,19 +188,18 @@
 void ShaderDiskCacheEntry::Cache() {
   DCHECK(CalledOnValidThread());
 
-  // The Entry* passed to the cache must stay alive even if this class is
-  // deleted, so store it in the callback.
-  auto entry = std::make_unique<disk_cache::Entry*>(nullptr);
-  disk_cache::Entry** closure_owned_entry_ptr = entry.get();
-  auto callback = base::Bind(&OnEntryOpenComplete<ShaderDiskCacheEntry>,
-                             weak_ptr_factory_.GetWeakPtr(),
-                             base::Passed(std::move(entry)));
+  // The Entry* passed to the cache may be used after this class is deleted or
+  // after the callback is deleted, so make it ref counted.
+  auto entry_ptr =
+      base::MakeRefCounted<base::RefCountedData<disk_cache::Entry*>>();
+  auto callback = base::BindOnce(&OnEntryOpenComplete<ShaderDiskCacheEntry>,
+                                 weak_ptr_factory_.GetWeakPtr(), entry_ptr);
 
-  int rv = cache_->backend()->OpenEntry(key_, net::HIGHEST,
-                                        closure_owned_entry_ptr, callback);
+  int rv = cache_->backend()->OpenEntry(key_, net::HIGHEST, &entry_ptr->data,
+                                        std::move(callback));
 
   if (rv != net::ERR_IO_PENDING) {
-    entry_ = *closure_owned_entry_ptr;
+    entry_ = entry_ptr->data;
     OnOpComplete(rv);
   }
 }
@@ -236,19 +237,18 @@
 
   op_type_ = CREATE_ENTRY;
 
-  // The Entry* passed to the cache must stay alive even if this class is
-  // deleted, so store it in the callback.
-  auto entry = std::make_unique<disk_cache::Entry*>(nullptr);
-  disk_cache::Entry** closure_owned_entry_ptr = entry.get();
-  auto callback = base::Bind(&OnEntryOpenComplete<ShaderDiskCacheEntry>,
-                             weak_ptr_factory_.GetWeakPtr(),
-                             base::Passed(std::move(entry)));
+  // The Entry* passed to the cache may be used after this class is deleted or
+  // after the callback is deleted, so make it ref counted.
+  auto entry_ptr =
+      base::MakeRefCounted<base::RefCountedData<disk_cache::Entry*>>();
+  auto callback = base::BindOnce(&OnEntryOpenComplete<ShaderDiskCacheEntry>,
+                                 weak_ptr_factory_.GetWeakPtr(), entry_ptr);
 
   int create_rv = cache_->backend()->CreateEntry(
-      key_, net::HIGHEST, closure_owned_entry_ptr, callback);
+      key_, net::HIGHEST, &entry_ptr->data, std::move(callback));
 
   if (create_rv != net::ERR_IO_PENDING)
-    entry_ = *closure_owned_entry_ptr;
+    entry_ = entry_ptr->data;
   return create_rv;
 }
 
@@ -328,18 +328,17 @@
   if (!iter_)
     iter_ = cache_->backend()->CreateIterator();
 
-  // The Entry* passed to the cache must stay alive even if this class is
-  // deleted, so store it in the callback.
-  auto entry = std::make_unique<disk_cache::Entry*>(nullptr);
-  disk_cache::Entry** closure_owned_entry_ptr = entry.get();
-  auto callback = base::Bind(&OnEntryOpenComplete<ShaderDiskReadHelper>,
-                             weak_ptr_factory_.GetWeakPtr(),
-                             base::Passed(std::move(entry)));
+  // The Entry* passed to the cache may be used after this class is deleted or
+  // after the callback is deleted, so make it ref counted.
+  auto entry_ptr =
+      base::MakeRefCounted<base::RefCountedData<disk_cache::Entry*>>();
+  auto callback = base::BindOnce(&OnEntryOpenComplete<ShaderDiskReadHelper>,
+                                 weak_ptr_factory_.GetWeakPtr(), entry_ptr);
 
-  int rv = iter_->OpenNextEntry(closure_owned_entry_ptr, callback);
+  int rv = iter_->OpenNextEntry(&entry_ptr->data, std::move(callback));
 
   if (rv != net::ERR_IO_PENDING)
-    entry_ = *closure_owned_entry_ptr;
+    entry_ = entry_ptr->data;
   return rv;
 }
 
diff --git a/headless/lib/headless_devtools_client_browsertest.cc b/headless/lib/headless_devtools_client_browsertest.cc
index f764285..7519a75e 100644
--- a/headless/lib/headless_devtools_client_browsertest.cc
+++ b/headless/lib/headless_devtools_client_browsertest.cc
@@ -179,7 +179,7 @@
  public:
   explicit HeadlessDevToolsClientChangeWindowStateTest(
       browser::WindowState state)
-      : state_(state){};
+      : state_(state) {}
 
   void RunDevTooledTest() override {
     SetWindowState(
@@ -214,7 +214,7 @@
  public:
   HeadlessDevToolsClientMinimizeWindowTest()
       : HeadlessDevToolsClientChangeWindowStateTest(
-            browser::WindowState::MINIMIZED){};
+            browser::WindowState::MINIMIZED) {}
 };
 
 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsClientMinimizeWindowTest);
@@ -224,7 +224,7 @@
  public:
   HeadlessDevToolsClientMaximizeWindowTest()
       : HeadlessDevToolsClientChangeWindowStateTest(
-            browser::WindowState::MAXIMIZED){};
+            browser::WindowState::MAXIMIZED) {}
 };
 
 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsClientMaximizeWindowTest);
@@ -234,7 +234,7 @@
  public:
   HeadlessDevToolsClientFullscreenWindowTest()
       : HeadlessDevToolsClientChangeWindowStateTest(
-            browser::WindowState::FULLSCREEN){};
+            browser::WindowState::FULLSCREEN) {}
 };
 
 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsClientFullscreenWindowTest);
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc
index b984f6d..fb5703b7 100644
--- a/headless/test/headless_protocol_browsertest.cc
+++ b/headless/test/headless_protocol_browsertest.cc
@@ -205,9 +205,9 @@
   }
 
 // Headless-specific tests
-HEADLESS_PROTOCOL_TEST(VirtualTimeBasics, "emulation/virtual-time-basics.js");
+HEADLESS_PROTOCOL_TEST(VirtualTimeBasics, "emulation/virtual-time-basics.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeInterrupt,
-                       "emulation/virtual-time-interrupt.js");
+                       "emulation/virtual-time-interrupt.js")
 #if defined(OS_LINUX)
 #define MAYBE_VirtualTimeCrossProcessNavigation \
   DISABLED_VirtualTimeCrossProcessNavigation
@@ -216,33 +216,33 @@
   VirtualTimeCrossProcessNavigation
 #endif
 HEADLESS_PROTOCOL_TEST(MAYBE_VirtualTimeCrossProcessNavigation,
-                       "emulation/virtual-time-cross-process-navigation.js");
+                       "emulation/virtual-time-cross-process-navigation.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeDetachFrame,
-                       "emulation/virtual-time-detach-frame.js");
-HEADLESS_PROTOCOL_TEST(VirtualTimeNoBlock404, "emulation/virtual-time-404.js");
+                       "emulation/virtual-time-detach-frame.js")
+HEADLESS_PROTOCOL_TEST(VirtualTimeNoBlock404, "emulation/virtual-time-404.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeLocalStorage,
-                       "emulation/virtual-time-local-storage.js");
+                       "emulation/virtual-time-local-storage.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimePendingScript,
-                       "emulation/virtual-time-pending-script.js");
+                       "emulation/virtual-time-pending-script.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeHtmlImport,
-                       "emulation/virtual-time-html-import.js");
+                       "emulation/virtual-time-html-import.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeRedirect,
-                       "emulation/virtual-time-redirect.js");
+                       "emulation/virtual-time-redirect.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeSessionStorage,
-                       "emulation/virtual-time-session-storage.js");
+                       "emulation/virtual-time-session-storage.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeStarvation,
-                       "emulation/virtual-time-starvation.js");
-HEADLESS_PROTOCOL_TEST(VirtualTimeVideo, "emulation/virtual-time-video.js");
+                       "emulation/virtual-time-starvation.js")
+HEADLESS_PROTOCOL_TEST(VirtualTimeVideo, "emulation/virtual-time-video.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeErrorLoop,
-                       "emulation/virtual-time-error-loop.js");
+                       "emulation/virtual-time-error-loop.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeFetchStream,
-                       "emulation/virtual-time-fetch-stream.js");
+                       "emulation/virtual-time-fetch-stream.js")
 HEADLESS_PROTOCOL_TEST(VirtualTimeDialogWhileLoading,
-                       "emulation/virtual-time-dialog-while-loading.js");
+                       "emulation/virtual-time-dialog-while-loading.js")
 
 // Flaky Test crbug.com/859382
 HEADLESS_PROTOCOL_TEST(DISABLED_VirtualTimeHistoryNavigation,
-                       "emulation/virtual-time-history-navigation.js");
+                       "emulation/virtual-time-history-navigation.js")
 
 // http://crbug.com/633321
 #if defined(OS_ANDROID)
@@ -253,9 +253,9 @@
 #define MAYBE_VirtualTimeTimerSuspend VirtualTimeTimerSuspend
 #endif
 HEADLESS_PROTOCOL_TEST(MAYBE_VirtualTimeTimerOrder,
-                       "emulation/virtual-time-timer-order.js");
+                       "emulation/virtual-time-timer-order.js")
 HEADLESS_PROTOCOL_TEST(MAYBE_VirtualTimeTimerSuspend,
-                       "emulation/virtual-time-timer-suspended.js");
+                       "emulation/virtual-time-timer-suspended.js")
 #undef MAYBE_VirtualTimeTimerOrder
 #undef MAYBE_VirtualTimeTimerSuspend
 
@@ -324,93 +324,92 @@
 #endif
 
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(CompositorBasicRaf,
-                                  "emulation/compositor-basic-raf.js");
+                                  "emulation/compositor-basic-raf.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     CompositorImageAnimation,
-    "emulation/compositor-image-animation-test.js");
+    "emulation/compositor-image-animation-test.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(CompositorCssAnimation,
-                                  "emulation/compositor-css-animation-test.js");
+                                  "emulation/compositor-css-animation-test.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(VirtualTimeControllerTest,
-                                  "helpers/virtual-time-controller-test.js");
+                                  "helpers/virtual-time-controller-test.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererHelloWorld,
-                                  "sanity/renderer-hello-world.js");
+                                  "sanity/renderer-hello-world.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererOverrideTitleJsEnabled,
-    "sanity/renderer-override-title-js-enabled.js");
+    "sanity/renderer-override-title-js-enabled.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererOverrideTitleJsDisabled,
-    "sanity/renderer-override-title-js-disabled.js");
+    "sanity/renderer-override-title-js-disabled.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererJavaScriptConsoleErrors,
-    "sanity/renderer-javascript-console-errors.js");
+    "sanity/renderer-javascript-console-errors.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererDelayedCompletion,
-                                  "sanity/renderer-delayed-completion.js");
+                                  "sanity/renderer-delayed-completion.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererClientRedirectChain,
-                                  "sanity/renderer-client-redirect-chain.js");
+                                  "sanity/renderer-client-redirect-chain.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererClientRedirectChainNoJs,
-    "sanity/renderer-client-redirect-chain-no-js.js");
+    "sanity/renderer-client-redirect-chain-no-js.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererServerRedirectChain,
-                                  "sanity/renderer-server-redirect-chain.js");
+                                  "sanity/renderer-server-redirect-chain.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererServerRedirectToFailure,
-    "sanity/renderer-server-redirect-to-failure.js");
+    "sanity/renderer-server-redirect-to-failure.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererServerRedirectRelativeChain,
-    "sanity/renderer-server-redirect-relative-chain.js");
+    "sanity/renderer-server-redirect-relative-chain.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererMixedRedirectChain,
-                                  "sanity/renderer-mixed-redirect-chain.js");
+                                  "sanity/renderer-mixed-redirect-chain.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererFramesRedirectChain,
-                                  "sanity/renderer-frames-redirect-chain.js");
+                                  "sanity/renderer-frames-redirect-chain.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererDoubleRedirect,
-                                  "sanity/renderer-double-redirect.js");
+                                  "sanity/renderer-double-redirect.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererRedirectAfterCompletion,
-    "sanity/renderer-redirect-after-completion.js");
-HEADLESS_PROTOCOL_COMPOSITOR_TEST(
-    RendererRedirect307PostMethod,
-    "sanity/renderer-redirect-307-post-method.js");
+    "sanity/renderer-redirect-after-completion.js")
+HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirect307PostMethod,
+                                  "sanity/renderer-redirect-307-post-method.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirectPostChain,
-                                  "sanity/renderer-redirect-post-chain.js");
+                                  "sanity/renderer-redirect-post-chain.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirect307PutMethod,
-                                  "sanity/renderer-redirect-307-put-method.js");
+                                  "sanity/renderer-redirect-307-put-method.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirect303PutGet,
-                                  "sanity/renderer-redirect-303-put-get.js");
+                                  "sanity/renderer-redirect-303-put-get.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirectBaseUrl,
-                                  "sanity/renderer-redirect-base-url.js");
+                                  "sanity/renderer-redirect-base-url.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirectNonAsciiUrl,
-                                  "sanity/renderer-redirect-non-ascii-url.js");
+                                  "sanity/renderer-redirect-non-ascii-url.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirectEmptyUrl,
-                                  "sanity/renderer-redirect-empty-url.js");
+                                  "sanity/renderer-redirect-empty-url.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirectInvalidUrl,
-                                  "sanity/renderer-redirect-invalid-url.js");
+                                  "sanity/renderer-redirect-invalid-url.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirectKeepsFragment,
-                                  "sanity/renderer-redirect-keeps-fragment.js");
+                                  "sanity/renderer-redirect-keeps-fragment.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererRedirectReplacesFragment,
-    "sanity/renderer-redirect-replaces-fragment.js");
+    "sanity/renderer-redirect-replaces-fragment.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererRedirectNewFragment,
-                                  "sanity/renderer-redirect-new-fragment.js");
+                                  "sanity/renderer-redirect-new-fragment.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererWindowLocationFragments,
-    "sanity/renderer-window-location-fragments.js");
+    "sanity/renderer-window-location-fragments.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCookieSetFromJs,
-                                  "sanity/renderer-cookie-set-from-js.js");
+                                  "sanity/renderer-cookie-set-from-js.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(
     RendererCookieSetFromJsNoCookies,
-    "sanity/renderer-cookie-set-from-js-no-cookies.js");
+    "sanity/renderer-cookie-set-from-js-no-cookies.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCookieUpdatedFromJs,
-                                  "sanity/renderer-cookie-updated-from-js.js");
+                                  "sanity/renderer-cookie-updated-from-js.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererInCrossOriginObject,
-                                  "sanity/renderer-in-cross-origin-object.js");
+                                  "sanity/renderer-in-cross-origin-object.js")
 
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererContentSecurityPolicy,
-                                  "sanity/renderer-content-security-policy.js");
+                                  "sanity/renderer-content-security-policy.js")
 
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererFrameLoadEvents,
-                                  "sanity/renderer-frame-load-events.js");
+                                  "sanity/renderer-frame-load-events.js")
 HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCssUrlFilter,
-                                  "sanity/renderer-css-url-filter.js");
-HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCanvas, "sanity/renderer-canvas.js");
+                                  "sanity/renderer-css-url-filter.js")
+HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCanvas, "sanity/renderer-canvas.js")
 
 }  // namespace headless
diff --git a/headless/test/test_network_interceptor.cc b/headless/test/test_network_interceptor.cc
index ae1ea7e2..0d48acd 100644
--- a/headless/test/test_network_interceptor.cc
+++ b/headless/test/test_network_interceptor.cc
@@ -34,7 +34,7 @@
     binding_.set_connection_error_handler(
         base::BindOnce([](RedirectLoader* self) { delete self; }, this));
     NotifyRedirect(std::move(url));
-  };
+  }
 
   void FollowRedirect(const std::vector<std::string>& removed_headers,
                       const net::HttpRequestHeaders& modified_headers,
diff --git a/ios/chrome/browser/autofill/personal_data_manager_factory.cc b/ios/chrome/browser/autofill/personal_data_manager_factory.cc
index 986d3784..87ec039 100644
--- a/ios/chrome/browser/autofill/personal_data_manager_factory.cc
+++ b/ios/chrome/browser/autofill/personal_data_manager_factory.cc
@@ -16,7 +16,6 @@
 #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/history/history_service_factory.h"
-#include "ios/chrome/browser/signin/gaia_cookie_manager_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
 #include "ios/chrome/browser/web_data_service_factory.h"
 
@@ -42,7 +41,6 @@
   DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(ios::HistoryServiceFactory::GetInstance());
   DependsOn(ios::WebDataServiceFactory::GetInstance());
-  DependsOn(ios::GaiaCookieManagerServiceFactory::GetInstance());
 }
 
 PersonalDataManagerFactory::~PersonalDataManagerFactory() {}
@@ -63,8 +61,6 @@
       autofill_db, nullptr, chrome_browser_state->GetPrefs(),
       IdentityManagerFactory::GetForBrowserState(chrome_browser_state),
       AutofillProfileValidatorFactory::GetInstance(), history_service,
-      ios::GaiaCookieManagerServiceFactory::GetForBrowserState(
-          chrome_browser_state),
       chrome_browser_state->IsOffTheRecord());
   return service;
 }
diff --git a/ios/chrome/browser/component_updater/ios_component_updater_configurator.cc b/ios/chrome/browser/component_updater/ios_component_updater_configurator.cc
index 88c7877..921a0ee 100644
--- a/ios/chrome/browser/component_updater/ios_component_updater_configurator.cc
+++ b/ios/chrome/browser/component_updater/ios_component_updater_configurator.cc
@@ -15,11 +15,13 @@
 #include "components/component_updater/component_updater_command_line_config_policy.h"
 #include "components/component_updater/configurator_impl.h"
 #include "components/update_client/activity_data_service.h"
+#include "components/update_client/network.h"
 #include "components/update_client/protocol_handler.h"
 #include "components/update_client/update_query_params.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/google/google_brand.h"
 #include "ios/chrome/common/channel_info.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/service_manager/public/cpp/connector.h"
 
 namespace component_updater {
@@ -45,8 +47,8 @@
   std::string GetOSLongName() const override;
   base::flat_map<std::string, std::string> ExtraRequestParams() const override;
   std::string GetDownloadPreference() const override;
-  scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactory()
-      const override;
+  scoped_refptr<update_client::NetworkFetcherFactory> GetNetworkFetcherFactory()
+      override;
   std::unique_ptr<service_manager::Connector> CreateServiceManagerConnector()
       const override;
   bool EnabledDeltas() const override;
@@ -66,6 +68,7 @@
   friend class base::RefCountedThreadSafe<IOSConfigurator>;
 
   ConfiguratorImpl configurator_impl_;
+  scoped_refptr<update_client::NetworkFetcherFactory> network_fetcher_factory_;
 
   ~IOSConfigurator() override {}
 };
@@ -137,9 +140,14 @@
   return configurator_impl_.GetDownloadPreference();
 }
 
-scoped_refptr<network::SharedURLLoaderFactory>
-IOSConfigurator::URLLoaderFactory() const {
-  return GetApplicationContext()->GetSharedURLLoaderFactory();
+scoped_refptr<update_client::NetworkFetcherFactory>
+IOSConfigurator::GetNetworkFetcherFactory() {
+  if (!network_fetcher_factory_) {
+    network_fetcher_factory_ =
+        base::MakeRefCounted<update_client::NetworkFetcherFactory>(
+            GetApplicationContext()->GetSharedURLLoaderFactory());
+  }
+  return network_fetcher_factory_;
 }
 
 std::unique_ptr<service_manager::Connector>
diff --git a/ios/chrome/browser/ui/authentication/cells/BUILD.gn b/ios/chrome/browser/ui/authentication/cells/BUILD.gn
index 5363891..f6fd043 100644
--- a/ios/chrome/browser/ui/authentication/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/cells/BUILD.gn
@@ -11,8 +11,6 @@
     "account_control_item.mm",
     "legacy_account_control_item.h",
     "legacy_account_control_item.mm",
-    "signin_promo_item.h",
-    "signin_promo_item.mm",
     "signin_promo_view.h",
     "signin_promo_view.mm",
     "signin_promo_view_configurator.h",
@@ -50,7 +48,6 @@
   sources = [
     "account_control_item_unittest.mm",
     "legacy_account_control_item_unittest.mm",
-    "signin_promo_item_unittest.mm",
     "signin_promo_view_unittest.mm",
     "table_view_account_item_unittest.mm",
   ]
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_item.h b/ios/chrome/browser/ui/authentication/cells/signin_promo_item.h
deleted file mode 100644
index 1a254a4..0000000
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_item.h
+++ /dev/null
@@ -1,33 +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 IOS_CHROME_BROWSER_UI_AUTHENTICATION_CELLS_SIGNIN_PROMO_ITEM_H_
-#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_CELLS_SIGNIN_PROMO_ITEM_H_
-
-#import <UIKit/UIKit.h>
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
-
-@class SigninPromoView;
-@class SigninPromoViewConfigurator;
-
-// TODO(crbug.com/894800): Remove this.
-// SigninPromoItem is an item that configures a SigninPromoCell cell.
-@interface SigninPromoItem : CollectionViewItem
-
-// Configures the SigninPromoView view from SigninPromoCell.
-@property(nonatomic, strong) SigninPromoViewConfigurator* configurator;
-
-@end
-
-// Cell representation for SigninPromoItem. The cell contains only a
-// SigninPromoView view.
-@interface SigninPromoCell : MDCCollectionViewCell
-
-@property(nonatomic, strong) SigninPromoView* signinPromoView;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_CELLS_SIGNIN_PROMO_ITEM_H_
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_item.mm b/ios/chrome/browser/ui/authentication/cells/signin_promo_item.mm
deleted file mode 100644
index 0c13a454..0000000
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_item.mm
+++ /dev/null
@@ -1,106 +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.
-
-#import "ios/chrome/browser/ui/authentication/cells/signin_promo_item.h"
-
-#include "components/unified_consent/feature.h"
-#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view.h"
-#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h"
-#include "ios/chrome/browser/ui/util/ui_util.h"
-#import "ios/chrome/common/ui_util/constraints_ui_util.h"
-#include "ios/chrome/grit/ios_chromium_strings.h"
-#include "ios/chrome/grit/ios_strings.h"
-#include "ui/base/l10n/l10n_util.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-// Padding for SignInPromoView.
-const CGFloat kSignInPromoViewPadding = 10;
-}  // namespace
-
-@implementation SigninPromoItem
-
-@synthesize configurator = _configurator;
-
-- (instancetype)initWithType:(NSInteger)type {
-  self = [super initWithType:type];
-  if (self) {
-    // |accessibilityIdentifier| is passed to the cell in -[CollectionViewItem
-    // configureCell:].
-    self.accessibilityIdentifier = @"SigninPromoCell";
-    self.cellClass = [SigninPromoCell class];
-  }
-  return self;
-}
-
-#pragma mark - CollectionViewItem
-
-- (void)configureCell:(SigninPromoCell*)cell {
-  [super configureCell:cell];
-  if (unified_consent::IsUnifiedConsentFeatureEnabled()) {
-    cell.signinPromoView.textLabel.text =
-        l10n_util::GetNSString(IDS_IOS_SIGNIN_PROMO_SETTINGS_WITH_UNITY);
-  } else {
-    cell.signinPromoView.textLabel.text =
-        l10n_util::GetNSString(IDS_IOS_SIGNIN_PROMO_SETTINGS);
-  }
-  [_configurator configureSigninPromoView:cell.signinPromoView];
-}
-
-@end
-
-@implementation SigninPromoCell
-
-@synthesize signinPromoView = _signinPromoView;
-
-- (instancetype)initWithFrame:(CGRect)frame {
-  self = [super initWithFrame:frame];
-  if (self) {
-    UIView* contentView = self.contentView;
-    _signinPromoView = [[SigninPromoView alloc] initWithFrame:self.bounds];
-    _signinPromoView.translatesAutoresizingMaskIntoConstraints = NO;
-    [contentView addSubview:_signinPromoView];
-
-    if (IsUIRefreshPhase1Enabled()) {
-      [NSLayoutConstraint activateConstraints:@[
-        [_signinPromoView.leadingAnchor
-            constraintEqualToAnchor:contentView.leadingAnchor
-                           constant:kSignInPromoViewPadding],
-        [_signinPromoView.trailingAnchor
-            constraintEqualToAnchor:contentView.trailingAnchor
-                           constant:-kSignInPromoViewPadding],
-        [_signinPromoView.topAnchor
-            constraintEqualToAnchor:contentView.topAnchor
-                           constant:kSignInPromoViewPadding],
-        [_signinPromoView.bottomAnchor
-            constraintEqualToAnchor:contentView.bottomAnchor
-                           constant:-kSignInPromoViewPadding],
-      ]];
-    } else {
-      AddSameConstraints(_signinPromoView, contentView);
-    }
-  }
-  return self;
-}
-
-// Implements -layoutSubviews as per instructions in documentation for
-// +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:].
-- (void)layoutSubviews {
-  [super layoutSubviews];
-
-  // Adjust the text label preferredMaxLayoutWidth when the parent's width
-  // changes, for instance on screen rotation.
-  CGFloat parentWidth = CGRectGetWidth(self.bounds);
-  _signinPromoView.textLabel.preferredMaxLayoutWidth =
-      parentWidth - 2 * _signinPromoView.horizontalPadding;
-
-  // Re-layout with the new preferred width to allow the label to adjust its
-  // height.
-  [super layoutSubviews];
-}
-
-@end
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_item_unittest.mm b/ios/chrome/browser/ui/authentication/cells/signin_promo_item_unittest.mm
deleted file mode 100644
index cf35a2f..0000000
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_item_unittest.mm
+++ /dev/null
@@ -1,39 +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.
-
-#import "ios/chrome/browser/ui/authentication/cells/signin_promo_item.h"
-
-#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view.h"
-#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-#import "third_party/ocmock/OCMock/OCMock.h"
-#include "third_party/ocmock/gtest_support.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-using SigninPromoItemTest = PlatformTest;
-
-// Tests that SigninPromoItem creates and configures correctly SigninPromoCell.
-TEST_F(SigninPromoItemTest, ConfigureCell) {
-  SigninPromoViewConfigurator* configurator =
-      OCMStrictClassMock([SigninPromoViewConfigurator class]);
-  SigninPromoItem* item = [[SigninPromoItem alloc] initWithType:0];
-  item.configurator = configurator;
-
-  id cell = [[[item cellClass] alloc] init];
-  ASSERT_TRUE([cell isMemberOfClass:[SigninPromoCell class]]);
-
-  SigninPromoCell* signInCell = cell;
-  EXPECT_NE(nil, signInCell.signinPromoView);
-  EXPECT_TRUE(
-      [signInCell.signinPromoView isMemberOfClass:[SigninPromoView class]]);
-  SigninPromoView* signinPromoView = signInCell.signinPromoView;
-  OCMExpect([configurator configureSigninPromoView:signinPromoView]);
-  [item configureCell:signInCell];
-  EXPECT_NE(nil, signinPromoView.textLabel.text);
-  EXPECT_OCMOCK_VERIFY((id)configurator);
-}
diff --git a/ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm b/ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm
index 59c0421..760bf629 100644
--- a/ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm
@@ -12,7 +12,6 @@
 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/material_components/chrome_app_bar_view_controller.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
diff --git a/ios/chrome/browser/ui/autofill/cells/BUILD.gn b/ios/chrome/browser/ui/autofill/cells/BUILD.gn
index 553233f..c981086 100644
--- a/ios/chrome/browser/ui/autofill/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/cells/BUILD.gn
@@ -15,12 +15,14 @@
   ]
 
   deps = [
+    "resources:autofill_edit_item_icon",
     "//components/resources",
     "//components/strings",
     "//ios/chrome/app/strings",
     "//ios/chrome/app/theme",
     "//ios/chrome/browser",
     "//ios/chrome/browser/ui",
+    "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/autofill:autofill_ui",
     "//ios/chrome/browser/ui/collection_view/cells",
     "//ios/chrome/browser/ui/colors",
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h
index 6be342cf..fc2d726 100644
--- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h
+++ b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h
@@ -23,9 +23,6 @@
 // An icon identifying the text field or its current value, if any.
 @property(nonatomic, copy) UIImage* identifyingIcon;
 
-// The inputView for the text field, if any.
-@property(nonatomic, strong) UIPickerView* inputView;
-
 // The field type this item is describing.
 @property(nonatomic, assign) AutofillUIType autofillUIType;
 
@@ -60,6 +57,9 @@
 // |textFieldValue|.
 @property(nonatomic, readonly, strong) UITextField* textField;
 
+// Whether the icon showing that the cell is editable should be displayed.
+@property(nonatomic, assign) BOOL editIconDisplayed;
+
 - (void)setIdentifyingIcon:(UIImage*)icon;
 
 @end
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm
index 81a541e8a..5e9595e 100644
--- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm
+++ b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm
@@ -6,6 +6,7 @@
 
 #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
+#include "ios/chrome/browser/ui/ui_feature_flags.h"
 #import "ios/chrome/browser/ui/util/rtl_geometry.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
@@ -17,6 +18,8 @@
 namespace {
 // Minimum gap between the label and the text field.
 const CGFloat kLabelAndFieldGap = 5;
+// Height/width of the edit icon.
+const CGFloat kEditIconLength = 18;
 }  // namespace
 
 @implementation AutofillEditItem
@@ -54,14 +57,19 @@
     cell.textField.backgroundColor = styler.tableViewBackgroundColor;
   }
   cell.textField.enabled = self.textFieldEnabled;
-  cell.textField.textColor =
-      self.textFieldEnabled
-          ? UIColorFromRGB(kTableViewTextLabelColorBlue)
-          : UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor);
+  if (base::FeatureList::IsEnabled(kSettingsRefresh)) {
+    cell.textField.textColor =
+        UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor);
+    cell.editIconDisplayed = self.textFieldEnabled;
+  } else {
+    cell.textField.textColor =
+        self.textFieldEnabled
+            ? UIColorFromRGB(kTableViewTextLabelColorBlue)
+            : UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor);
+  }
   [cell.textField addTarget:self
                      action:@selector(textFieldChanged:)
            forControlEvents:UIControlEventEditingChanged];
-  cell.textField.inputView = self.inputView;
   cell.textField.returnKeyType = self.returnKeyType;
   cell.textField.keyboardType = self.keyboardType;
   cell.textField.autocapitalizationType = self.autoCapitalizationType;
@@ -85,6 +93,9 @@
 @property(nonatomic, strong) NSLayoutConstraint* textFieldTrailingConstraint;
 @property(nonatomic, strong) NSLayoutConstraint* textLabelTrailingConstraint;
 
+@property(nonatomic, strong) NSLayoutConstraint* editIconHeightConstraint;
+@property(nonatomic, strong) NSLayoutConstraint* iconTrailingConstraint;
+
 // When they are activated, the label and the text field are on one line.
 // They conflict with the |accessibilityConstraints|.
 @property(nonatomic, strong) NSArray<NSLayoutConstraint*>* standardConstraints;
@@ -96,6 +107,9 @@
 // UIImageView containing the icon identifying |textField| or its current value.
 @property(nonatomic, readonly, strong) UIImageView* identifyingIconView;
 
+// UIImageView containing the icon indicating that |textField| is editable.
+@property(nonatomic, strong) UIImageView* editIconView;
+
 @end
 
 @implementation AutofillEditCell
@@ -137,16 +151,29 @@
     _identifyingIconView.translatesAutoresizingMaskIntoConstraints = NO;
     [contentView addSubview:_identifyingIconView];
 
+    // Edit icon.
+    UIImage* editImage = [[UIImage imageNamed:@"autofill_edit_item_icon"]
+        imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
+    _editIconView = [[UIImageView alloc] initWithImage:editImage];
+    _editIconView.tintColor =
+        UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor);
+    _editIconView.translatesAutoresizingMaskIntoConstraints = NO;
+    [contentView addSubview:_editIconView];
+
     // Set up the icons size constraints. They are activated here and updated in
     // layoutSubviews.
     _iconHeightConstraint =
         [_identifyingIconView.heightAnchor constraintEqualToConstant:0];
     _iconWidthConstraint =
         [_identifyingIconView.widthAnchor constraintEqualToConstant:0];
+    _editIconHeightConstraint =
+        [_editIconView.heightAnchor constraintEqualToConstant:0];
 
     _textFieldTrailingConstraint = [_textField.trailingAnchor
-        constraintEqualToAnchor:_identifyingIconView.leadingAnchor];
+        constraintEqualToAnchor:_editIconView.leadingAnchor];
     _textLabelTrailingConstraint = [_textLabel.trailingAnchor
+        constraintEqualToAnchor:_editIconView.leadingAnchor];
+    _iconTrailingConstraint = [_editIconView.trailingAnchor
         constraintEqualToAnchor:_identifyingIconView.leadingAnchor];
 
     _standardConstraints = @[
@@ -177,8 +204,14 @@
                          constant:-kTableViewHorizontalSpacing],
       [_identifyingIconView.centerYAnchor
           constraintEqualToAnchor:contentView.centerYAnchor],
+      [_editIconView.centerYAnchor
+          constraintEqualToAnchor:contentView.centerYAnchor],
       _iconHeightConstraint,
       _iconWidthConstraint,
+      _iconTrailingConstraint,
+      _editIconHeightConstraint,
+      [_editIconView.widthAnchor
+          constraintEqualToAnchor:_editIconView.heightAnchor],
     ]];
     AddOptionalVerticalPadding(contentView, _textLabel,
                                kTableViewLargeVerticalSpacing);
@@ -194,18 +227,35 @@
 
 #pragma mark Public
 
+- (void)setEditIconDisplayed:(BOOL)editIconDisplayed {
+  if (editIconDisplayed == _editIconDisplayed)
+    return;
+
+  _editIconDisplayed = editIconDisplayed;
+  self.editIconView.hidden = !editIconDisplayed;
+  if (editIconDisplayed) {
+    self.textFieldTrailingConstraint.constant = -kLabelAndFieldGap;
+    self.textLabelTrailingConstraint.constant = -kLabelAndFieldGap;
+
+    _editIconHeightConstraint.constant = kEditIconLength;
+  } else {
+    self.textFieldTrailingConstraint.constant = 0;
+    self.textLabelTrailingConstraint.constant = 0;
+
+    _editIconHeightConstraint.constant = 0;
+  }
+}
+
 - (void)setIdentifyingIcon:(UIImage*)icon {
   self.identifyingIconView.image = icon;
   if (icon) {
-    self.textFieldTrailingConstraint.constant = -kLabelAndFieldGap;
-    self.textLabelTrailingConstraint.constant = -kLabelAndFieldGap;
+    self.iconTrailingConstraint.constant = -kLabelAndFieldGap;
 
     // Set the size constraints of the icon view to the dimensions of the image.
     self.iconHeightConstraint.constant = icon.size.height;
     self.iconWidthConstraint.constant = icon.size.width;
   } else {
-    self.textFieldTrailingConstraint.constant = 0;
-    self.textLabelTrailingConstraint.constant = 0;
+    self.iconTrailingConstraint.constant = 0;
     self.iconHeightConstraint.constant = 0;
     self.iconWidthConstraint.constant = 0;
   }
diff --git a/ios/chrome/browser/ui/autofill/cells/resources/BUILD.gn b/ios/chrome/browser/ui/autofill/cells/resources/BUILD.gn
new file mode 100644
index 0000000..5695705
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/cells/resources/BUILD.gn
@@ -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("//build/config/ios/asset_catalog.gni")
+
+imageset("autofill_edit_item_icon") {
+  sources = [
+    "autofill_edit_item_icon.imageset/Contents.json",
+    "autofill_edit_item_icon.imageset/autofill_edit_item_icon@2x.png",
+    "autofill_edit_item_icon.imageset/autofill_edit_item_icon@3x.png",
+  ]
+}
diff --git a/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/Contents.json b/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/Contents.json
new file mode 100644
index 0000000..d275f8b
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+    "images": [
+        {
+            "idiom": "universal",
+            "scale": "1x"
+        },
+        {
+            "idiom": "universal",
+            "scale": "2x",
+            "filename": "autofill_edit_item_icon@2x.png"
+        },
+        {
+            "idiom": "universal",
+            "scale": "3x",
+            "filename": "autofill_edit_item_icon@3x.png"
+        }
+    ],
+    "info": {
+        "version": 1,
+        "author": "xcode"
+    }
+}
diff --git a/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/autofill_edit_item_icon@2x.png b/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/autofill_edit_item_icon@2x.png
new file mode 100644
index 0000000..0ab39585
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/autofill_edit_item_icon@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/autofill_edit_item_icon@3x.png b/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/autofill_edit_item_icon@3x.png
new file mode 100644
index 0000000..98e17e1
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/cells/resources/autofill_edit_item_icon.imageset/autofill_edit_item_icon@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/collection_view/cells/BUILD.gn b/ios/chrome/browser/ui/collection_view/cells/BUILD.gn
index dfa675b..14cbf934 100644
--- a/ios/chrome/browser/ui/collection_view/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/collection_view/cells/BUILD.gn
@@ -12,8 +12,6 @@
     "collection_view_account_item.mm",
     "collection_view_cell_constants.h",
     "collection_view_cell_style.h",
-    "collection_view_detail_item.h",
-    "collection_view_detail_item.mm",
     "collection_view_footer_item.h",
     "collection_view_footer_item.mm",
     "collection_view_item.h",
@@ -22,8 +20,6 @@
     "collection_view_switch_item.mm",
     "collection_view_text_cell.h",
     "collection_view_text_cell.mm",
-    "collection_view_text_item.h",
-    "collection_view_text_item.mm",
   ]
 
   deps = [
@@ -63,11 +59,9 @@
     "MDCCollectionViewCell+Chrome_unittest.mm",
     "activity_indicator_cell_unittest.mm",
     "collection_view_account_item_unittest.mm",
-    "collection_view_detail_item_unittest.mm",
     "collection_view_footer_item_unittest.mm",
     "collection_view_item_unittest.mm",
     "collection_view_switch_item_unittest.mm",
-    "collection_view_text_item_unittest.mm",
   ]
 
   deps = [
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h b/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h
deleted file mode 100644
index f584135..0000000
--- a/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h
+++ /dev/null
@@ -1,57 +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 IOS_CHROME_BROWSER_UI_COLLECTION_VIEW_CELLS_COLLECTION_VIEW_DETAIL_ITEM_H_
-#define IOS_CHROME_BROWSER_UI_COLLECTION_VIEW_CELLS_COLLECTION_VIEW_DETAIL_ITEM_H_
-
-#import <UIKit/UIKit.h>
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
-
-// CollectionViewDetailItem is the model class corresponding to
-// CollectionViewDetailCell.
-@interface CollectionViewDetailItem : CollectionViewItem
-
-// The accessory type to display on the trailing edge of the cell.
-@property(nonatomic) MDCCollectionViewCellAccessoryType accessoryType;
-
-// The main text string.
-@property(nonatomic, copy) NSString* text;
-
-// The detail text string.
-@property(nonatomic, copy) NSString* detailText;
-
-@end
-
-// CollectionViewDetailCell implements an MDCCollectionViewCell subclass
-// containing two text labels: a "main" label and a "detail" label.  The two
-// labels are laid out side-by-side and fill the full width of the cell.  Labels
-// are truncated as needed to fit in the cell.
-@interface CollectionViewDetailCell : MDCCollectionViewCell
-
-// UILabels corresponding to |text| and |detailText| from the item.
-@property(nonatomic, readonly, strong) UILabel* textLabel;
-@property(nonatomic, readonly, strong) UILabel* detailTextLabel;
-
-// The amount of horizontal space to provide to each of the labels. These values
-// are determined with the following logic:
-//
-// - If there is sufficient room (after accounting for margins) for the full
-//   width of each label, use the current width of each label.
-// - If not, use the current width of the main label and a clipped width for the
-//   detail label.
-// - Unless the main label wants more than 75% of the available width and the
-//   detail label wants 25% or less of the available width, in which case use a
-//   clipped width for the main label and the current width of the detail label.
-// - If both labels want more width than their guaranteed minimums (75% and
-//   25%), use the guaranteed minimum amount for each.
-//
-// Exposed for testing.
-@property(nonatomic, readonly) CGFloat textLabelTargetWidth;
-@property(nonatomic, readonly) CGFloat detailTextLabelTargetWidth;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_COLLECTION_VIEW_CELLS_COLLECTION_VIEW_DETAIL_ITEM_H_
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.mm b/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.mm
deleted file mode 100644
index 3f00c5c..0000000
--- a/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.mm
+++ /dev/null
@@ -1,173 +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.
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
-
-#include <algorithm>
-
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
-#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-// Padding used on the leading and trailing edges of the cell and between the
-// two labels.
-const CGFloat kHorizontalPadding = 16;
-
-// Padding used on the top and bottom edges of the cell.
-const CGFloat kVerticalPadding = 16;
-
-// Minimum proportion of the available width to guarantee to the main and detail
-// labels.
-const CGFloat kMinTextWidthRatio = 0.75f;
-const CGFloat kMinDetailTextWidthRatio = 0.25f;
-}
-
-@implementation CollectionViewDetailItem
-
-@synthesize accessoryType = _accessoryType;
-@synthesize text = _text;
-@synthesize detailText = _detailText;
-
-- (instancetype)initWithType:(NSInteger)type {
-  self = [super initWithType:type];
-  if (self) {
-    self.cellClass = [CollectionViewDetailCell class];
-  }
-  return self;
-}
-
-#pragma mark CollectionViewItem
-
-- (void)configureCell:(CollectionViewDetailCell*)cell {
-  [super configureCell:cell];
-  [cell cr_setAccessoryType:self.accessoryType];
-  cell.textLabel.text = self.text;
-  cell.detailTextLabel.text = self.detailText;
-}
-
-@end
-
-@implementation CollectionViewDetailCell {
-  NSLayoutConstraint* _textLabelWidthConstraint;
-  NSLayoutConstraint* _detailTextLabelWidthConstraint;
-}
-
-@synthesize textLabel = _textLabel;
-@synthesize detailTextLabel = _detailTextLabel;
-
-- (instancetype)initWithFrame:(CGRect)frame {
-  self = [super initWithFrame:frame];
-  if (self) {
-    self.isAccessibilityElement = YES;
-    UIView* contentView = self.contentView;
-
-    _textLabel = [[UILabel alloc] init];
-    _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
-    _textLabel.backgroundColor = [UIColor clearColor];
-    [contentView addSubview:_textLabel];
-
-    _textLabel.font = [[MDCTypography fontLoader] mediumFontOfSize:14];
-    _textLabel.textColor = [[MDCPalette greyPalette] tint900];
-
-    _detailTextLabel = [[UILabel alloc] init];
-    _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
-    _detailTextLabel.backgroundColor = [UIColor clearColor];
-    [contentView addSubview:_detailTextLabel];
-
-    _detailTextLabel.font = [[MDCTypography fontLoader] regularFontOfSize:14];
-    _detailTextLabel.textColor = [[MDCPalette greyPalette] tint500];
-
-    // Set up the width constraints. They are activated here and updated in
-    // layoutSubviews.
-    _textLabelWidthConstraint =
-        [_textLabel.widthAnchor constraintEqualToConstant:0];
-    _detailTextLabelWidthConstraint =
-        [_detailTextLabel.widthAnchor constraintEqualToConstant:0];
-
-    [NSLayoutConstraint activateConstraints:@[
-      // Fix the leading and trailing edges of the text labels.
-      [_textLabel.leadingAnchor
-          constraintEqualToAnchor:contentView.leadingAnchor
-                         constant:kHorizontalPadding],
-      [_detailTextLabel.trailingAnchor
-          constraintEqualToAnchor:contentView.trailingAnchor
-                         constant:-kHorizontalPadding],
-
-      // Set up the top and bottom constraints for |_textLabel| and align the
-      // baselines of the two text labels.
-      [_textLabel.topAnchor constraintEqualToAnchor:contentView.topAnchor
-                                           constant:kVerticalPadding],
-      [_textLabel.bottomAnchor constraintEqualToAnchor:contentView.bottomAnchor
-                                              constant:-kVerticalPadding],
-      [_detailTextLabel.firstBaselineAnchor
-          constraintEqualToAnchor:_textLabel.firstBaselineAnchor],
-
-      _textLabelWidthConstraint,
-      _detailTextLabelWidthConstraint,
-    ]];
-  }
-  return self;
-}
-
-// Updates the layout constraints of the text labels and then calls the
-// superclass's implementation of layoutSubviews which can then take account of
-// the new constraints.
-- (void)layoutSubviews {
-  [super layoutSubviews];
-
-  // Size the labels in order to determine how much width they want.
-  [self.textLabel sizeToFit];
-  [self.detailTextLabel sizeToFit];
-
-  // Update the width constraints.
-  _textLabelWidthConstraint.constant = self.textLabelTargetWidth;
-  _detailTextLabelWidthConstraint.constant = self.detailTextLabelTargetWidth;
-
-  // Now invoke the layout.
-  [super layoutSubviews];
-}
-
-- (CGFloat)textLabelTargetWidth {
-  CGFloat availableWidth =
-      self.contentView.bounds.size.width - (3 * kHorizontalPadding);
-  CGFloat textLabelWidth = self.textLabel.frame.size.width;
-  CGFloat detailTextLabelWidth = self.detailTextLabel.frame.size.width;
-
-  if (textLabelWidth + detailTextLabelWidth <= availableWidth)
-    return textLabelWidth;
-
-  return std::max(
-      availableWidth - detailTextLabelWidth,
-      std::min(availableWidth * kMinTextWidthRatio, textLabelWidth));
-}
-
-- (CGFloat)detailTextLabelTargetWidth {
-  CGFloat availableWidth =
-      self.contentView.bounds.size.width - (3 * kHorizontalPadding);
-  CGFloat textLabelWidth = self.textLabel.frame.size.width;
-  CGFloat detailTextLabelWidth = self.detailTextLabel.frame.size.width;
-
-  if (textLabelWidth + detailTextLabelWidth <= availableWidth)
-    return detailTextLabelWidth;
-
-  return std::max(availableWidth - textLabelWidth,
-                  std::min(availableWidth * kMinDetailTextWidthRatio,
-                           detailTextLabelWidth));
-}
-
-- (NSString*)accessibilityLabel {
-  return self.textLabel.text;
-}
-
-- (NSString*)accessibilityValue {
-  return self.detailTextLabel.text;
-}
-
-@end
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item_unittest.mm b/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item_unittest.mm
deleted file mode 100644
index 8607b4a..0000000
--- a/ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item_unittest.mm
+++ /dev/null
@@ -1,121 +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.
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-using CollectionViewDetailItemTest = PlatformTest;
-
-// Tests that the UILabels are set properly after a call to |configureCell:|.
-TEST_F(CollectionViewDetailItemTest, TextLabels) {
-  CollectionViewDetailItem* item =
-      [[CollectionViewDetailItem alloc] initWithType:0];
-  NSString* mainText = @"Main text";
-  NSString* detailText = @"Detail text";
-
-  item.text = mainText;
-  item.detailText = detailText;
-
-  id cell = [[[item cellClass] alloc] init];
-  ASSERT_TRUE([cell isMemberOfClass:[CollectionViewDetailCell class]]);
-
-  CollectionViewDetailCell* detailCell = cell;
-  EXPECT_FALSE(detailCell.textLabel.text);
-  EXPECT_FALSE(detailCell.detailTextLabel.text);
-
-  [item configureCell:cell];
-  EXPECT_NSEQ(mainText, detailCell.textLabel.text);
-  EXPECT_NSEQ(detailText, detailCell.detailTextLabel.text);
-}
-
-using CollectionViewDetailCellTest = PlatformTest;
-
-// Tests that each of the two text labels is provided with the correct amount
-// of space.
-TEST_F(CollectionViewDetailCellTest, TextLabelTargetWidths) {
-  // Make the cell 148 wide so that after allocating 3 * kHorizontalPadding (16)
-  // space for the margins and area between the labels, there is 100 available.
-  // Accordingly, in each of the cases below where the sum of the desired label
-  // widths exceeds 100, the sum of the constraints should equal 100.
-  CollectionViewDetailCell* cell = [[CollectionViewDetailCell alloc]
-      initWithFrame:CGRectMake(0, 0, 148, 100)];
-
-  CGRect textLabelRect = CGRectZero;
-  CGRect detailTextLabelRect = CGRectZero;
-
-  // If there is enough room for both, each should be allowed its full width.
-  textLabelRect.size.width = 50;
-  detailTextLabelRect.size.width = 40;
-  cell.textLabel.frame = textLabelRect;
-  cell.detailTextLabel.frame = detailTextLabelRect;
-  EXPECT_EQ(50, [cell textLabelTargetWidth]);
-  EXPECT_EQ(40, [cell detailTextLabelTargetWidth]);
-
-  // Even if there's only exactly enough room for both.
-  textLabelRect.size.width = 30;
-  detailTextLabelRect.size.width = 70;
-  cell.textLabel.frame = textLabelRect;
-  cell.detailTextLabel.frame = detailTextLabelRect;
-  EXPECT_EQ(30, [cell textLabelTargetWidth]);
-  EXPECT_EQ(70, [cell detailTextLabelTargetWidth]);
-
-  // And even if one of the labels is really big.
-  textLabelRect.size.width = 5;
-  detailTextLabelRect.size.width = 95;
-  cell.textLabel.frame = textLabelRect;
-  cell.detailTextLabel.frame = detailTextLabelRect;
-  EXPECT_EQ(5, [cell textLabelTargetWidth]);
-  EXPECT_EQ(95, [cell detailTextLabelTargetWidth]);
-
-  // But once they exceed the available width, start clipping the detail label.
-  textLabelRect.size.width = 51;
-  detailTextLabelRect.size.width = 50;
-  cell.textLabel.frame = textLabelRect;
-  cell.detailTextLabel.frame = detailTextLabelRect;
-  EXPECT_EQ(51, [cell textLabelTargetWidth]);
-  EXPECT_EQ(49, [cell detailTextLabelTargetWidth]);
-
-  textLabelRect.size.width = 25;
-  detailTextLabelRect.size.width = 90;
-  cell.textLabel.frame = textLabelRect;
-  cell.detailTextLabel.frame = detailTextLabelRect;
-  EXPECT_EQ(25, [cell textLabelTargetWidth]);
-  EXPECT_EQ(75, [cell detailTextLabelTargetWidth]);
-
-  textLabelRect.size.width = 70;
-  detailTextLabelRect.size.width = 50;
-  cell.textLabel.frame = textLabelRect;
-  cell.detailTextLabel.frame = detailTextLabelRect;
-  EXPECT_EQ(70, [cell textLabelTargetWidth]);
-  EXPECT_EQ(30, [cell detailTextLabelTargetWidth]);
-
-  // On the other hand, if the text label wants more than 75% of the width, clip
-  // it instead.
-  textLabelRect.size.width = 90;
-  detailTextLabelRect.size.width = 20;
-  cell.textLabel.frame = textLabelRect;
-  cell.detailTextLabel.frame = detailTextLabelRect;
-  EXPECT_EQ(80, [cell textLabelTargetWidth]);
-  EXPECT_EQ(20, [cell detailTextLabelTargetWidth]);
-
-  // If both want more than their guaranteed minimum (75 and 25), give them each
-  // the minimum.
-  textLabelRect.size.width = 90;
-  detailTextLabelRect.size.width = 50;
-  cell.textLabel.frame = textLabelRect;
-  cell.detailTextLabel.frame = detailTextLabelRect;
-  EXPECT_EQ(75, [cell textLabelTargetWidth]);
-  EXPECT_EQ(25, [cell detailTextLabelTargetWidth]);
-}
-
-}  // namespace
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h b/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h
deleted file mode 100644
index 37e2b90..0000000
--- a/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h
+++ /dev/null
@@ -1,55 +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 IOS_CHROME_BROWSER_UI_COLLECTION_VIEW_CELLS_COLLECTION_VIEW_TEXT_ITEM_H_
-#define IOS_CHROME_BROWSER_UI_COLLECTION_VIEW_CELLS_COLLECTION_VIEW_TEXT_ITEM_H_
-
-#import <UIKit/UIKit.h>
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
-
-// Collection view item to represent and configure a CollectionViewTextCell.
-@interface CollectionViewTextItem : CollectionViewItem
-
-// The accessory type for the represented cell.
-@property(nonatomic) MDCCollectionViewCellAccessoryType accessoryType;
-
-// The main text to display.
-@property(nonatomic, nullable, copy) NSString* text;
-
-// The secondary text to display.
-@property(nonatomic, nullable, copy) NSString* detailText;
-
-// The font of the main text. Default is the medium Roboto font of size 14.
-@property(nonatomic, null_resettable, copy) UIFont* textFont;
-
-// The color of the main text. Default is the 900 tint color of the grey
-// palette.
-@property(nonatomic, null_resettable, copy) UIColor* textColor;
-
-// The maximum number of lines of the main text. Default is 1.
-@property(nonatomic, assign) NSInteger numberOfTextLines;
-
-// The font of the secondary text. Default is the regular Roboto font of size
-// 14.
-@property(nonatomic, null_resettable, copy) UIFont* detailTextFont;
-
-// The color of the secondary text. Default is the 500 tint color of the grey
-// palette.
-@property(nonatomic, null_resettable, copy) UIColor* detailTextColor;
-
-// The maximum number of lines of the secondary text. Default is 1.
-@property(nonatomic, assign) NSInteger numberOfDetailTextLines;
-
-// Command to trigger when the cell is tapped. The default value is 0.
-@property(nonatomic, assign) NSInteger commandID;
-
-// YES if the cell should be tappable. The text color is grayed out when set to
-// NO (only if no |textColor| has been set). The default value is YES.
-@property(nonatomic, assign) BOOL enabled;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_COLLECTION_VIEW_CELLS_COLLECTION_VIEW_TEXT_ITEM_H_
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.mm b/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.mm
deleted file mode 100644
index 23de748..0000000
--- a/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.mm
+++ /dev/null
@@ -1,98 +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.
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
-
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_cell.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
-#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-@implementation CollectionViewTextItem
-
-@synthesize accessoryType = _accessoryType;
-@synthesize text = _text;
-@synthesize detailText = _detailText;
-@synthesize textFont = _textFont;
-@synthesize textColor = _textColor;
-@synthesize numberOfTextLines = _numberOfTextLines;
-@synthesize detailTextFont = _detailTextFont;
-@synthesize detailTextColor = _detailTextColor;
-@synthesize numberOfDetailTextLines = _numberOfDetailTextLines;
-@synthesize commandID = _commandID;
-@synthesize enabled = _enabled;
-
-- (instancetype)initWithType:(NSInteger)type {
-  self = [super initWithType:type];
-  if (self) {
-    self.cellClass = [CollectionViewTextCell class];
-    _numberOfTextLines = 1;
-    _numberOfDetailTextLines = 1;
-    _enabled = YES;
-  }
-  return self;
-}
-
-- (UIFont*)textFont {
-  if (!_textFont) {
-    _textFont = [[MDCTypography fontLoader] mediumFontOfSize:14];
-  }
-  return _textFont;
-}
-
-- (UIColor*)textColor {
-  if (!_textColor) {
-    return self.enabled ? [[MDCPalette greyPalette] tint900]
-                        : [[MDCPalette greyPalette] tint500];
-  }
-  return _textColor;
-}
-
-- (UIFont*)detailTextFont {
-  if (!_detailTextFont) {
-    _detailTextFont = [[MDCTypography fontLoader] regularFontOfSize:14];
-  }
-  return _detailTextFont;
-}
-
-- (UIColor*)detailTextColor {
-  if (!_detailTextColor) {
-    _detailTextColor = [[MDCPalette greyPalette] tint500];
-  }
-  return _detailTextColor;
-}
-
-#pragma mark CollectionViewItem
-
-- (void)configureCell:(CollectionViewTextCell*)cell {
-  [super configureCell:cell];
-  [cell cr_setAccessoryType:self.accessoryType];
-  cell.textLabel.text = self.text;
-  cell.detailTextLabel.text = self.detailText;
-  cell.isAccessibilityElement = YES;
-  if ([self.accessibilityLabel length] != 0) {
-    cell.accessibilityLabel = self.accessibilityLabel;
-  } else {
-    if (self.detailText.length == 0) {
-      cell.accessibilityLabel = self.text;
-    } else {
-      cell.accessibilityLabel =
-          [NSString stringWithFormat:@"%@, %@", self.text, self.detailText];
-    }
-  }
-
-  // Styling.
-  cell.textLabel.font = self.textFont;
-  cell.textLabel.textColor = self.textColor;
-  cell.textLabel.numberOfLines = self.numberOfTextLines;
-  cell.detailTextLabel.font = self.detailTextFont;
-  cell.detailTextLabel.textColor = self.detailTextColor;
-  cell.detailTextLabel.numberOfLines = self.numberOfDetailTextLines;
-}
-
-@end
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item_unittest.mm b/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item_unittest.mm
deleted file mode 100644
index 8111772a..0000000
--- a/ios/chrome/browser/ui/collection_view/cells/collection_view_text_item_unittest.mm
+++ /dev/null
@@ -1,82 +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.
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
-
-#import <CoreGraphics/CoreGraphics.h>
-#import <UIKit/UIKit.h>
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_cell.h"
-#import "ios/chrome/browser/ui/collection_view/cells/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-using CollectionViewTextItemTest = PlatformTest;
-
-// Test that accessory type is copied over to the cell from the item.
-TEST_F(CollectionViewTextItemTest, ConfigureCellPortsAccessoryType) {
-  CollectionViewTextItem* item =
-      [[CollectionViewTextItem alloc] initWithType:0];
-  item.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
-  CollectionViewTextCell* cell = [[[item cellClass] alloc] init];
-  EXPECT_TRUE([cell isMemberOfClass:[CollectionViewTextCell class]]);
-  EXPECT_EQ(MDCCollectionViewCellAccessoryNone, [cell accessoryType]);
-  [item configureCell:cell];
-  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark, [cell accessoryType]);
-}
-
-// Test that text properties are copied over to the cell from the item.
-TEST_F(CollectionViewTextItemTest, ConfigureCellPortsTextCellProperties) {
-  CollectionViewTextItem* item =
-      [[CollectionViewTextItem alloc] initWithType:0];
-  item.text = @"some text";
-  item.detailText = @"some detail text";
-  CollectionViewTextCell* cell = [[[item cellClass] alloc] init];
-  EXPECT_TRUE([cell isMemberOfClass:[CollectionViewTextCell class]]);
-  EXPECT_FALSE([cell textLabel].text);
-  EXPECT_FALSE([cell detailTextLabel].text);
-  [item configureCell:cell];
-  EXPECT_NSEQ(@"some text", [cell textLabel].text);
-  EXPECT_NSEQ(@"some detail text", [cell detailTextLabel].text);
-}
-
-// Test that if the item has no accessibilityLabel, the cell gets one composed
-// of the text and detailText.
-TEST_F(CollectionViewTextItemTest, ConfigureCellDerivesAccessibilityLabel) {
-  CollectionViewTextItem* item =
-      [[CollectionViewTextItem alloc] initWithType:0];
-  item.text = @"some text";
-  item.detailText = @"some detail text";
-  CollectionViewTextCell* cell = [[[item cellClass] alloc] init];
-  EXPECT_TRUE([cell isMemberOfClass:[CollectionViewTextCell class]]);
-  EXPECT_FALSE([cell textLabel].accessibilityLabel);
-  [item configureCell:cell];
-  EXPECT_NSEQ(@"some text, some detail text", [cell accessibilityLabel]);
-}
-
-// Test that if the item has a non-empty accessibilityLabel, this is copied
-// over to the cell.
-TEST_F(CollectionViewTextItemTest, ConfigureCellPortsAccessibilityLabel) {
-  CollectionViewTextItem* item =
-      [[CollectionViewTextItem alloc] initWithType:0];
-  item.accessibilityLabel = @"completely different label";
-  // Also set text and detailText to verify that the derived
-  // accessibilityLabel is not composed of those.
-  item.text = @"some text";
-  item.detailText = @"some detail text";
-  CollectionViewTextCell* cell = [[[item cellClass] alloc] init];
-  EXPECT_TRUE([cell isMemberOfClass:[CollectionViewTextCell class]]);
-  EXPECT_FALSE([cell textLabel].accessibilityLabel);
-  [item configureCell:cell];
-  EXPECT_NSEQ(@"completely different label", [cell accessibilityLabel]);
-}
-
-}  // namespace
diff --git a/ios/chrome/browser/ui/collection_view/collection_view_controller_test.mm b/ios/chrome/browser/ui/collection_view/collection_view_controller_test.mm
index 001e70e..f04cdc70 100644
--- a/ios/chrome/browser/ui/collection_view/collection_view_controller_test.mm
+++ b/ios/chrome/browser/ui/collection_view/collection_view_controller_test.mm
@@ -6,11 +6,10 @@
 
 #include "base/logging.h"
 #import "base/mac/foundation_util.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
+#import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 
@@ -118,9 +117,11 @@
 void CollectionViewControllerTest::CheckTextCellTitle(NSString* expected_title,
                                                       int section,
                                                       int item) {
-  CollectionViewTextItem* cell = GetCollectionViewItem(section, item);
-  EXPECT_NSEQ(expected_title, cell.text);
-  EXPECT_FALSE(cell.detailText);
+  id cell = GetCollectionViewItem(section, item);
+  ASSERT_TRUE([cell respondsToSelector:@selector(text)]);
+  EXPECT_NSEQ(expected_title, [cell text]);
+  ASSERT_TRUE([cell respondsToSelector:@selector(detailText)]);
+  EXPECT_FALSE([cell detailText]);
 }
 
 void CollectionViewControllerTest::CheckTextCellTitleWithId(
@@ -135,9 +136,11 @@
     NSString* expected_subtitle,
     int section,
     int item) {
-  CollectionViewTextItem* cell = GetCollectionViewItem(section, item);
-  EXPECT_NSEQ(expected_title, cell.text);
-  EXPECT_NSEQ(expected_subtitle, cell.detailText);
+  id cell = GetCollectionViewItem(section, item);
+  ASSERT_TRUE([cell respondsToSelector:@selector(text)]);
+  EXPECT_NSEQ(expected_title, [cell text]);
+  ASSERT_TRUE([cell respondsToSelector:@selector(detailText)]);
+  EXPECT_NSEQ(expected_subtitle, [cell detailText]);
 }
 
 void CollectionViewControllerTest::CheckDetailItemTextWithIds(
@@ -145,9 +148,9 @@
     int expected_detail_text_id,
     int section_id,
     int item_id) {
-  CollectionViewDetailItem* item = GetCollectionViewItem(section_id, item_id);
-  EXPECT_NSEQ(l10n_util::GetNSString(expected_text_id), item.text);
-  EXPECT_NSEQ(l10n_util::GetNSString(expected_detail_text_id), item.detailText);
+  CheckTextCellTitleAndSubtitle(l10n_util::GetNSString(expected_text_id),
+                                l10n_util::GetNSString(expected_detail_text_id),
+                                section_id, item_id);
 }
 
 void CollectionViewControllerTest::CheckSwitchCellStateAndTitle(
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
index 5302111..8e16c07d 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -9,7 +9,6 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/time/time.h"
 #include "components/strings/grit/components_strings.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/commands/snackbar_commands.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater_unittest.mm
index 273fd0c..daf9f0e8 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater_unittest.mm
@@ -4,7 +4,6 @@
 
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h"
 
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_text_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/suggested_content.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/mediator_util.mm b/ios/chrome/browser/ui/content_suggestions/mediator_util.mm
index 77b928a..b223621 100644
--- a/ios/chrome/browser/ui/content_suggestions/mediator_util.mm
+++ b/ios/chrome/browser/ui/content_suggestions/mediator_util.mm
@@ -7,7 +7,6 @@
 #include "base/callback.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/ntp_snippets/category.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
diff --git a/ios/chrome/browser/ui/history/history_entry_inserter.mm b/ios/chrome/browser/ui/history/history_entry_inserter.mm
index ef94a213..453a3e8 100644
--- a/ios/chrome/browser/ui/history/history_entry_inserter.mm
+++ b/ios/chrome/browser/ui/history/history_entry_inserter.mm
@@ -7,7 +7,6 @@
 #include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/time/time.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/history/history_entry_item_interface.h"
 #include "ios/chrome/browser/ui/history/history_util.h"
 #import "ios/chrome/browser/ui/list_model/list_model.h"
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.h
index 75bf5c4..91bf3ce 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.h
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.h
@@ -39,7 +39,6 @@
   void OnLineSelected(size_t line) override {}
   void UpdatePopupAppearance() override;
   void OnMatchIconUpdated(size_t match_index) override {}
-  void PaintUpdatesNow() override {}
   void OnDragCanceled() override {}
 
   void UpdateEditViewIcon();
diff --git a/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.h b/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.h
index 48dadb9..df601c06 100644
--- a/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.h
+++ b/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.h
@@ -45,4 +45,32 @@
 
 @end
 
+// CollectionViewDetailCell implements an MDCCollectionViewCell subclass
+// containing two text labels: a "main" label and a "detail" label.  The two
+// labels are laid out side-by-side and fill the full width of the cell.  Labels
+// are truncated as needed to fit in the cell.
+@interface CollectionViewDetailCell : MDCCollectionViewCell
+
+// UILabels corresponding to |text| and |detailText| from the item.
+@property(nonatomic, readonly, strong, nonnull) UILabel* textLabel;
+@property(nonatomic, readonly, strong, nonnull) UILabel* detailTextLabel;
+
+// The amount of horizontal space to provide to each of the labels. These values
+// are determined with the following logic:
+//
+// - If there is sufficient room (after accounting for margins) for the full
+//   width of each label, use the current width of each label.
+// - If not, use the current width of the main label and a clipped width for the
+//   detail label.
+// - Unless the main label wants more than 75% of the available width and the
+//   detail label wants 25% or less of the available width, in which case use a
+//   clipped width for the main label and the current width of the detail label.
+// - If both labels want more width than their guaranteed minimums (75% and
+//   25%), use the guaranteed minimum amount for each.
+//
+// Exposed for testing.
+@property(nonatomic, readonly) CGFloat textLabelTargetWidth;
+@property(nonatomic, readonly) CGFloat detailTextLabelTargetWidth;
+
+@end
 #endif  // IOS_CHROME_BROWSER_UI_PAYMENTS_CELLS_PAYMENTS_SELECTOR_EDIT_ITEM_H_
diff --git a/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.mm b/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.mm
index 3c01c660..763697c 100644
--- a/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.mm
+++ b/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.mm
@@ -4,8 +4,9 @@
 
 #import "ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.h"
 
+#include <algorithm>
+
 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 
@@ -13,6 +14,21 @@
 #error "This file requires ARC support."
 #endif
 
+namespace {
+
+// Padding used on the leading and trailing edges of the cell and between the
+// two labels.
+const CGFloat kHorizontalPadding = 16;
+
+// Padding used on the top and bottom edges of the cell.
+const CGFloat kVerticalPadding = 16;
+
+// Minimum proportion of the available width to guarantee to the main and detail
+// labels.
+const CGFloat kMinTextWidthRatio = 0.75f;
+const CGFloat kMinDetailTextWidthRatio = 0.25f;
+}
+
 @implementation PaymentsSelectorEditItem
 
 @synthesize accessoryType = _accessoryType;
@@ -85,3 +101,121 @@
 }
 
 @end
+
+@implementation CollectionViewDetailCell {
+  NSLayoutConstraint* _textLabelWidthConstraint;
+  NSLayoutConstraint* _detailTextLabelWidthConstraint;
+}
+
+@synthesize textLabel = _textLabel;
+@synthesize detailTextLabel = _detailTextLabel;
+
+- (instancetype)initWithFrame:(CGRect)frame {
+  self = [super initWithFrame:frame];
+  if (self) {
+    self.isAccessibilityElement = YES;
+    UIView* contentView = self.contentView;
+
+    _textLabel = [[UILabel alloc] init];
+    _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
+    _textLabel.backgroundColor = [UIColor clearColor];
+    [contentView addSubview:_textLabel];
+
+    _textLabel.font = [[MDCTypography fontLoader] mediumFontOfSize:14];
+    _textLabel.textColor = [[MDCPalette greyPalette] tint900];
+
+    _detailTextLabel = [[UILabel alloc] init];
+    _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
+    _detailTextLabel.backgroundColor = [UIColor clearColor];
+    [contentView addSubview:_detailTextLabel];
+
+    _detailTextLabel.font = [[MDCTypography fontLoader] regularFontOfSize:14];
+    _detailTextLabel.textColor = [[MDCPalette greyPalette] tint500];
+
+    // Set up the width constraints. They are activated here and updated in
+    // layoutSubviews.
+    _textLabelWidthConstraint =
+        [_textLabel.widthAnchor constraintEqualToConstant:0];
+    _detailTextLabelWidthConstraint =
+        [_detailTextLabel.widthAnchor constraintEqualToConstant:0];
+
+    [NSLayoutConstraint activateConstraints:@[
+      // Fix the leading and trailing edges of the text labels.
+      [_textLabel.leadingAnchor
+          constraintEqualToAnchor:contentView.leadingAnchor
+                         constant:kHorizontalPadding],
+      [_detailTextLabel.trailingAnchor
+          constraintEqualToAnchor:contentView.trailingAnchor
+                         constant:-kHorizontalPadding],
+
+      // Set up the top and bottom constraints for |_textLabel| and align the
+      // baselines of the two text labels.
+      [_textLabel.topAnchor constraintEqualToAnchor:contentView.topAnchor
+                                           constant:kVerticalPadding],
+      [_textLabel.bottomAnchor constraintEqualToAnchor:contentView.bottomAnchor
+                                              constant:-kVerticalPadding],
+      [_detailTextLabel.firstBaselineAnchor
+          constraintEqualToAnchor:_textLabel.firstBaselineAnchor],
+
+      _textLabelWidthConstraint,
+      _detailTextLabelWidthConstraint,
+    ]];
+  }
+  return self;
+}
+
+// Updates the layout constraints of the text labels and then calls the
+// superclass's implementation of layoutSubviews which can then take account of
+// the new constraints.
+- (void)layoutSubviews {
+  [super layoutSubviews];
+
+  // Size the labels in order to determine how much width they want.
+  [self.textLabel sizeToFit];
+  [self.detailTextLabel sizeToFit];
+
+  // Update the width constraints.
+  _textLabelWidthConstraint.constant = self.textLabelTargetWidth;
+  _detailTextLabelWidthConstraint.constant = self.detailTextLabelTargetWidth;
+
+  // Now invoke the layout.
+  [super layoutSubviews];
+}
+
+- (CGFloat)textLabelTargetWidth {
+  CGFloat availableWidth =
+      self.contentView.bounds.size.width - (3 * kHorizontalPadding);
+  CGFloat textLabelWidth = self.textLabel.frame.size.width;
+  CGFloat detailTextLabelWidth = self.detailTextLabel.frame.size.width;
+
+  if (textLabelWidth + detailTextLabelWidth <= availableWidth)
+    return textLabelWidth;
+
+  return std::max(
+      availableWidth - detailTextLabelWidth,
+      std::min(availableWidth * kMinTextWidthRatio, textLabelWidth));
+}
+
+- (CGFloat)detailTextLabelTargetWidth {
+  CGFloat availableWidth =
+      self.contentView.bounds.size.width - (3 * kHorizontalPadding);
+  CGFloat textLabelWidth = self.textLabel.frame.size.width;
+  CGFloat detailTextLabelWidth = self.detailTextLabel.frame.size.width;
+
+  if (textLabelWidth + detailTextLabelWidth <= availableWidth)
+    return detailTextLabelWidth;
+
+  return std::max(availableWidth - textLabelWidth,
+                  std::min(availableWidth * kMinDetailTextWidthRatio,
+                           detailTextLabelWidth));
+}
+
+- (NSString*)accessibilityLabel {
+  return self.textLabel.text;
+}
+
+- (NSString*)accessibilityValue {
+  return self.detailTextLabel.text;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item_unittests.mm b/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item_unittests.mm
index 9bf5828a..5e4f8e2 100644
--- a/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item_unittests.mm
+++ b/ios/chrome/browser/ui/payments/cells/payments_selector_edit_item_unittests.mm
@@ -4,7 +4,6 @@
 
 #import "ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.h"
 
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm
index 706270d..9957e59 100644
--- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm
@@ -10,8 +10,8 @@
 #import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
+#import "ios/chrome/browser/ui/payments/cells/payment_method_item.h"
 #import "ios/chrome/browser/ui/payments/cells/payments_selector_edit_item.h"
 #import "ios/chrome/browser/ui/payments/payment_request_edit_consumer.h"
 #import "ios/chrome/browser/ui/payments/payment_request_edit_view_controller_data_source.h"
@@ -43,7 +43,7 @@
 }
 
 - (CollectionViewItem*)headerItem {
-  return [[CollectionViewTextItem alloc] init];
+  return [[PaymentMethodItem alloc] init];
 }
 
 - (BOOL)shouldHideBackgroundForHeaderItem {
@@ -122,10 +122,10 @@
   ASSERT_EQ(5, NumberOfSections());
 
   // The header section is the first section and has one item of the type
-  // CollectionViewTextItem.
+  // PaymentMethodItem.
   ASSERT_EQ(1U, static_cast<unsigned int>(NumberOfItemsInSection(0)));
   id item = GetCollectionViewItem(0, 0);
-  EXPECT_TRUE([item isMemberOfClass:[CollectionViewTextItem class]]);
+  EXPECT_TRUE([item isMemberOfClass:[PaymentMethodItem class]]);
 
   // The next section has one item of the type LegacyAutofillEditItem.
   ASSERT_EQ(1U, static_cast<unsigned int>(NumberOfItemsInSection(1)));
diff --git a/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm
index 19d570f..0d9401aa 100644
--- a/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm
@@ -20,7 +20,6 @@
 #import "ios/chrome/browser/payments/payment_request_unittest_base.h"
 #include "ios/chrome/browser/payments/payment_request_util.h"
 #include "ios/chrome/browser/payments/test_payment_request.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/payments/cells/autofill_profile_item.h"
 #import "ios/chrome/browser/ui/payments/cells/payment_method_item.h"
diff --git a/ios/chrome/browser/ui/payments/payment_request_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_view_controller.mm
index 15dd11a..995e612c 100644
--- a/ios/chrome/browser/ui/payments/payment_request_view_controller.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_view_controller.mm
@@ -9,7 +9,6 @@
 #include "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/ui/autofill/cells/status_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
diff --git a/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm
index e488179b..44e43a8 100644
--- a/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm
@@ -15,7 +15,6 @@
 #include "ios/chrome/browser/payments/payment_request_test_util.h"
 #import "ios/chrome/browser/payments/payment_request_unittest_base.h"
 #import "ios/chrome/browser/ui/autofill/cells/status_item.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
 #import "ios/chrome/browser/ui/payments/cells/autofill_profile_item.h"
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn
index 7020b30..d40ada1 100644
--- a/ios/chrome/browser/ui/settings/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -38,8 +38,6 @@
     "sync_switch_item.mm",
     "table_view_clear_browsing_data_item.h",
     "table_view_clear_browsing_data_item.mm",
-    "text_and_error_item.h",
-    "text_and_error_item.mm",
     "version_item.h",
     "version_item.mm",
   ]
@@ -77,7 +75,6 @@
     "copied_to_chrome_item_unittest.mm",
     "passphrase_error_item_unittest.mm",
     "settings_multiline_detail_item_unittest.mm",
-    "text_and_error_item_unittest.mm",
     "version_item_unittest.mm",
   ]
 
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn b/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
index 78eac0e..f050c516 100644
--- a/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
@@ -4,12 +4,8 @@
 
 source_set("legacy") {
   sources = [
-    "legacy_account_signin_item.h",
-    "legacy_account_signin_item.mm",
     "legacy_settings_detail_item.h",
     "legacy_settings_detail_item.mm",
-    "legacy_sync_switch_item.h",
-    "legacy_sync_switch_item.mm",
   ]
 
   deps = [
@@ -25,22 +21,3 @@
 
   configs += [ "//build/config/compiler:enable_arc" ]
 }
-
-source_set("unit_tests") {
-  testonly = true
-  sources = [
-    "legacy_account_signin_item_unittest.mm",
-    "legacy_sync_switch_item_unittest.mm",
-  ]
-
-  deps = [
-    ":legacy",
-    "//components/browsing_data/core",
-    "//components/strings",
-    "//ios/third_party/material_components_ios",
-    "//testing/gtest",
-    "//ui/base",
-  ]
-
-  configs += [ "//build/config/compiler:enable_arc" ]
-}
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h
deleted file mode 100644
index 16edca5..0000000
--- a/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h
+++ /dev/null
@@ -1,40 +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 IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_ACCOUNT_SIGNIN_ITEM_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_ACCOUNT_SIGNIN_ITEM_H_
-
-#import <UIKit/UIKit.h>
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
-
-// LegacyAccountSignInItem is an Item that displays an Image, a title text label
-// and a detail text label.
-// This is intended to be used as an sign in Item which contains a default
-// avatar and information
-// letting the user know that they are not signed in, and that tapping on the
-// Item will allow them
-// to authenticate and sign in.
-
-@interface LegacyAccountSignInItem : CollectionViewItem
-
-// Item image.
-@property(nonatomic, copy) UIImage* image;
-
-@end
-
-// Cell representation for LegacyAccountSignInItem.
-@interface LegacyAccountSignInCell : MDCCollectionViewCell
-
-// Cell title.
-@property(nonatomic, readonly, strong) UILabel* textLabel;
-// Cell subtitle.
-@property(nonatomic, readonly, strong) UILabel* detailTextLabel;
-// Cell imageView.
-@property(nonatomic, strong) UIImageView* imageView;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_ACCOUNT_SIGNIN_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.mm
deleted file mode 100644
index c2282036..0000000
--- a/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.mm
+++ /dev/null
@@ -1,183 +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.
-
-#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h"
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
-#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
-#include "ios/chrome/grit/ios_chromium_strings.h"
-#include "ios/chrome/grit/ios_strings.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
-#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
-#include "ui/base/l10n/l10n_util.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-// Padding used on the leading and trailing edges of the cell.
-const CGFloat kHorizontalPadding = 16;
-
-// Padding used between the image and text.
-const CGFloat kHorizontalPaddingBetweenImageAndText = 10;
-
-// Image fixed horizontal size.
-const CGFloat kHorizontalImageFixedSize = 40;
-
-// Font size for the main text.
-const CGFloat kMainTextFontSize = 14;
-
-// Font size for detail text.
-const CGFloat kDetailTextFontSize = 14;
-}
-
-@implementation LegacyAccountSignInItem
-
-@synthesize image = _image;
-
-- (instancetype)initWithType:(NSInteger)type {
-  self = [super initWithType:type];
-  if (self) {
-    self.cellClass = [LegacyAccountSignInCell class];
-    self.accessibilityTraits |= UIAccessibilityTraitButton;
-  }
-  return self;
-}
-
-#pragma mark - CollectionViewItem
-
-- (void)configureCell:(LegacyAccountSignInCell*)cell {
-  [super configureCell:cell];
-  cell.textLabel.text =
-      l10n_util::GetNSString(IDS_IOS_SIGN_IN_TO_CHROME_SETTING_TITLE);
-  cell.detailTextLabel.text =
-      l10n_util::GetNSString(IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SUBTITLE);
-  cell.imageView.image = self.image;
-}
-
-@end
-
-@implementation LegacyAccountSignInCell
-
-@synthesize textLabel = _textLabel;
-@synthesize detailTextLabel = _detailTextLabel;
-@synthesize imageView = _imageView;
-
-- (instancetype)initWithFrame:(CGRect)frame {
-  self = [super initWithFrame:frame];
-  if (self) {
-    self.isAccessibilityElement = YES;
-    [self addSubviews];
-    [self setDefaultViewStyling];
-    [self setViewConstraints];
-  }
-  return self;
-}
-
-// Create and add subviews.
-- (void)addSubviews {
-  UIView* contentView = self.contentView;
-  contentView.clipsToBounds = YES;
-
-  _imageView = [[UIImageView alloc] init];
-  _imageView.translatesAutoresizingMaskIntoConstraints = NO;
-  [contentView addSubview:_imageView];
-
-  _textLabel = [[UILabel alloc] init];
-  _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
-  [contentView addSubview:_textLabel];
-
-  _detailTextLabel = [[UILabel alloc] init];
-  _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
-  [_detailTextLabel setNumberOfLines:3];
-  [contentView addSubview:_detailTextLabel];
-}
-
-- (void)setDefaultViewStyling {
-  _imageView.contentMode = UIViewContentModeCenter;
-  _imageView.layer.masksToBounds = YES;
-  _imageView.contentMode = UIViewContentModeScaleAspectFit;
-
-  _textLabel.font = [UIFont systemFontOfSize:kMainTextFontSize];
-  _textLabel.textColor = UIColorFromRGB(kUIKitMainTextColor);
-
-  _detailTextLabel.font = [UIFont systemFontOfSize:kDetailTextFontSize];
-  _detailTextLabel.textColor = UIColorFromRGB(kUIKitMultilineDetailTextColor);
-}
-
-- (void)setViewConstraints {
-  UIView* contentView = self.contentView;
-
-  // This guide is used to center the two leading textLabels.
-  UILayoutGuide* verticalCenteringGuide = [[UILayoutGuide alloc] init];
-  [contentView addLayoutGuide:verticalCenteringGuide];
-
-  [NSLayoutConstraint activateConstraints:@[
-    // Set leading anchors.
-    [_imageView.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor
-                                             constant:kHorizontalPadding],
-    [_detailTextLabel.leadingAnchor
-        constraintEqualToAnchor:_textLabel.leadingAnchor],
-    [_textLabel.leadingAnchor
-        constraintEqualToAnchor:_imageView.trailingAnchor
-                       constant:kHorizontalPaddingBetweenImageAndText],
-
-    // Fix image widths.
-    [_imageView.widthAnchor
-        constraintEqualToConstant:kHorizontalImageFixedSize],
-
-    // Set vertical anchors. This approach assumes the cell height is set by
-    // the view controller. Contents are pinned to centerY, rather than pushing
-    // against the top/bottom boundaries.
-    [_imageView.centerYAnchor
-        constraintEqualToAnchor:contentView.centerYAnchor],
-    [_textLabel.topAnchor
-        constraintEqualToAnchor:verticalCenteringGuide.topAnchor],
-    [_textLabel.bottomAnchor
-        constraintEqualToAnchor:_detailTextLabel.topAnchor],
-    [_detailTextLabel.bottomAnchor
-        constraintEqualToAnchor:verticalCenteringGuide.bottomAnchor],
-    [verticalCenteringGuide.centerYAnchor
-        constraintEqualToAnchor:contentView.centerYAnchor],
-    // Set trailing anchors.
-    [_detailTextLabel.trailingAnchor
-        constraintEqualToAnchor:contentView.trailingAnchor
-                       constant:-kHorizontalPadding],
-    [_textLabel.trailingAnchor
-        constraintLessThanOrEqualToAnchor:contentView.trailingAnchor
-                                 constant:-kHorizontalPadding],
-  ]];
-
-  // This is needed so the image doesn't get pushed out if both text and detail
-  // are long.
-  [_textLabel
-      setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
-                                      forAxis:UILayoutConstraintAxisHorizontal];
-  [_detailTextLabel
-      setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
-                                      forAxis:UILayoutConstraintAxisHorizontal];
-}
-
-#pragma mark - UICollectionReusableView
-
-- (void)prepareForReuse {
-  [super prepareForReuse];
-  _imageView.image = nil;
-  self.textLabel.text = nil;
-  self.detailTextLabel.text = nil;
-}
-
-#pragma mark - NSObject(Accessibility)
-
-- (NSString*)accessibilityLabel {
-  return l10n_util::GetNSString(IDS_IOS_SIGN_IN_TO_CHROME_SETTING_TITLE);
-}
-
-- (NSString*)accessibilityValue {
-  return [NSString stringWithFormat:@"%@, %@", self.textLabel.text,
-                                    self.detailTextLabel.text];
-}
-
-@end
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item_unittest.mm
deleted file mode 100644
index 9d5296f7..0000000
--- a/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item_unittest.mm
+++ /dev/null
@@ -1,38 +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.
-
-#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h"
-
-#import <CoreGraphics/CoreGraphics.h>
-#import <UIKit/UIKit.h>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-// Tests that the UIImage and UILabels are set properly after a call to
-// |configureCell:|.
-
-using LegacyAccountSignInItemTest = PlatformTest;
-
-TEST_F(LegacyAccountSignInItemTest, ImageView) {
-  LegacyAccountSignInItem* item =
-      [[LegacyAccountSignInItem alloc] initWithType:0];
-  UIImage* image = [[UIImage alloc] init];
-
-  item.image = image;
-
-  id cell = [[[item cellClass] alloc] init];
-  ASSERT_TRUE([cell isMemberOfClass:[LegacyAccountSignInCell class]]);
-
-  LegacyAccountSignInCell* signInCell = cell;
-  EXPECT_FALSE(signInCell.imageView.image);
-
-  [item configureCell:cell];
-  EXPECT_NSEQ(image, signInCell.imageView.image);
-}
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h
deleted file mode 100644
index 8998695..0000000
--- a/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h
+++ /dev/null
@@ -1,53 +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 IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_SYNC_SWITCH_ITEM_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_SYNC_SWITCH_ITEM_H_
-
-#import <UIKit/UIKit.h>
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
-
-@interface LegacySyncSwitchItem : CollectionViewItem
-
-// The title text to display.
-@property(nonatomic, copy) NSString* text;
-
-// The detail text to display.
-@property(nonatomic, copy) NSString* detailText;
-
-// The current state of the switch.
-@property(nonatomic, assign, getter=isOn) BOOL on;
-
-// Whether or not the switch is enabled.  Disabled switches are automatically
-// drawn as in the "off" state, with dimmed text.
-@property(nonatomic, assign, getter=isEnabled) BOOL enabled;
-
-// SyncSetupService::SyncableDatatype value for the item.
-@property(nonatomic, assign) NSInteger dataType;
-
-// Command to trigger when the switch is toggled. The default value is 0.
-@property(nonatomic, assign) NSInteger commandID;
-
-@end
-
-// Cell representation for AccountSignInItem.
-@interface LegacySyncSwitchCell : MDCCollectionViewCell
-
-// Cell title.
-@property(nonatomic, readonly, strong) UILabel* textLabel;
-
-// Cell subtitle.
-@property(nonatomic, readonly, strong) UILabel* detailTextLabel;
-
-// The switch view.
-@property(nonatomic, readonly, strong) UISwitch* switchView;
-
-// Returns the default text color used for the given |state|.
-+ (UIColor*)defaultTextColorForState:(UIControlState)state;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_SYNC_SWITCH_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.mm
deleted file mode 100644
index 55cc8f6e..0000000
--- a/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.mm
+++ /dev/null
@@ -1,206 +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.
-
-#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h"
-
-#include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
-#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
-#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
-#import "ios/chrome/common/ui_util/constraints_ui_util.h"
-#include "ios/chrome/grit/ios_strings.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
-#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
-#include "ui/base/l10n/l10n_util_mac.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-// Padding used on the leading and trailing edges of the cell.
-const CGFloat kHorizontalPadding = 16;
-
-// Padding used on the top and bottom edges of the cell.
-const CGFloat kVerticalPadding = 16;
-
-// Padding used between the switch and text.
-const CGFloat kHorizontalSwitchPadding = 10;
-}  // namespace
-
-#pragma mark - LegacySyncSwitchItem
-
-@implementation LegacySyncSwitchItem
-
-@synthesize text = _text;
-@synthesize detailText = _detailText;
-@synthesize on = _on;
-@synthesize enabled = _enabled;
-@synthesize dataType = _dataType;
-@synthesize commandID = _commandID;
-
-- (instancetype)initWithType:(NSInteger)type {
-  self = [super initWithType:type];
-  if (self) {
-    self.cellClass = [LegacySyncSwitchCell class];
-    self.enabled = YES;
-  }
-  return self;
-}
-
-- (void)configureCell:(LegacySyncSwitchCell*)cell {
-  [super configureCell:cell];
-  cell.textLabel.text = self.text;
-  cell.detailTextLabel.text = self.detailText;
-  cell.switchView.enabled = self.isEnabled;
-  cell.switchView.on = self.isOn;
-  cell.textLabel.textColor =
-      [LegacySyncSwitchCell defaultTextColorForState:cell.switchView.state];
-  if (self.isEnabled) {
-    cell.textLabel.textColor = [[MDCPalette greyPalette] tint900];
-    cell.switchView.enabled = YES;
-    cell.userInteractionEnabled = YES;
-  } else {
-    cell.textLabel.textColor = [[MDCPalette greyPalette] tint500];
-    cell.switchView.enabled = NO;
-    cell.userInteractionEnabled = NO;
-  }
-}
-
-@end
-
-@implementation LegacySyncSwitchCell
-
-@synthesize textLabel = _textLabel;
-@synthesize detailTextLabel = _detailTextLabel;
-@synthesize switchView = _switchView;
-
-- (instancetype)initWithFrame:(CGRect)frame {
-  self = [super initWithFrame:frame];
-  if (self) {
-    self.isAccessibilityElement = YES;
-
-    _textLabel = [[UILabel alloc] init];
-    _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
-    _textLabel.font = [UIFont systemFontOfSize:kUIKitMainFontSize];
-    _textLabel.textColor = UIColorFromRGB(kUIKitMainTextColor);
-    _textLabel.numberOfLines = 0;
-    [self.contentView addSubview:_textLabel];
-
-    _detailTextLabel = [[UILabel alloc] init];
-    _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
-    _detailTextLabel.font =
-        [UIFont systemFontOfSize:kUIKitMultilineDetailFontSize];
-    _detailTextLabel.textColor = UIColorFromRGB(kUIKitMultilineDetailTextColor);
-    _detailTextLabel.numberOfLines = 0;
-    [self.contentView addSubview:_detailTextLabel];
-
-    _switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
-    _switchView.translatesAutoresizingMaskIntoConstraints = NO;
-    _switchView.accessibilityHint = l10n_util::GetNSString(
-        IDS_IOS_TOGGLE_SETTING_SWITCH_ACCESSIBILITY_HINT);
-    _switchView.onTintColor = UIColorFromRGB(kUIKitSwitchTintColor);
-    [self.contentView addSubview:_switchView];
-
-    [self setConstraints];
-  }
-
-  return self;
-}
-
-- (void)setConstraints {
-  UIView* contentView = self.contentView;
-
-  [NSLayoutConstraint activateConstraints:@[
-    [_textLabel.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor
-                                             constant:kHorizontalPadding],
-    [_detailTextLabel.leadingAnchor
-        constraintEqualToAnchor:_textLabel.leadingAnchor],
-    [_switchView.trailingAnchor
-        constraintEqualToAnchor:contentView.trailingAnchor
-                       constant:-kHorizontalPadding],
-    [_textLabel.trailingAnchor
-        constraintLessThanOrEqualToAnchor:_switchView.leadingAnchor
-                                 constant:-kHorizontalSwitchPadding],
-    [_detailTextLabel.trailingAnchor
-        constraintEqualToAnchor:_textLabel.trailingAnchor],
-    [_textLabel.bottomAnchor
-        constraintEqualToAnchor:_detailTextLabel.topAnchor],
-    [_switchView.centerYAnchor
-        constraintEqualToAnchor:contentView.centerYAnchor],
-  ]];
-  AddOptionalVerticalPadding(contentView, _textLabel, _detailTextLabel,
-                             kVerticalPadding);
-}
-
-+ (UIColor*)defaultTextColorForState:(UIControlState)state {
-  MDCPalette* grey = [MDCPalette greyPalette];
-  return (state & UIControlStateDisabled) ? grey.tint500 : grey.tint900;
-}
-
-// Implement -layoutSubviews as per instructions in documentation for
-// +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:].
-- (void)layoutSubviews {
-  [super layoutSubviews];
-  // Adjust the text and detailText label preferredMaxLayoutWidth when the
-  // parent's width
-  // changes, for instance on screen rotation.
-  CGFloat prefferedMaxLayoutWidth = CGRectGetWidth(self.contentView.frame) -
-                                    CGRectGetWidth(_switchView.frame) -
-                                    2 * kHorizontalPadding -
-                                    kHorizontalSwitchPadding;
-  _textLabel.preferredMaxLayoutWidth = prefferedMaxLayoutWidth;
-  _detailTextLabel.preferredMaxLayoutWidth = prefferedMaxLayoutWidth;
-
-  // Re-layout with the new preferred width to allow the label to adjust its
-  // height.
-  [super layoutSubviews];
-}
-
-- (void)prepareForReuse {
-  [super prepareForReuse];
-  self.tag = 0;
-  self.textLabel.textColor = [[MDCPalette greyPalette] tint900];
-  [self.switchView setEnabled:YES];
-  [self setUserInteractionEnabled:YES];
-
-  [_switchView removeTarget:nil
-                     action:nil
-           forControlEvents:[_switchView allControlEvents]];
-}
-
-#pragma mark - UIAccessibility
-
-- (CGPoint)accessibilityActivationPoint {
-  // Center the activation point over the switch, so that double-tapping toggles
-  // the switch.
-  CGRect switchFrame =
-      UIAccessibilityConvertFrameToScreenCoordinates(_switchView.frame, self);
-  return CGPointMake(CGRectGetMidX(switchFrame), CGRectGetMidY(switchFrame));
-}
-
-- (NSString*)accessibilityHint {
-  if (_switchView.isEnabled) {
-    return _switchView.accessibilityHint;
-  } else {
-    return @"";
-  }
-}
-
-- (NSString*)accessibilityLabel {
-  if (_detailTextLabel.text) {
-    return [NSString
-        stringWithFormat:@"%@, %@", _textLabel.text, _detailTextLabel.text];
-  }
-  return _textLabel.text;
-}
-
-- (NSString*)accessibilityValue {
-  if (_switchView.on) {
-    return l10n_util::GetNSString(IDS_IOS_SETTING_ON);
-  } else {
-    return l10n_util::GetNSString(IDS_IOS_SETTING_OFF);
-  }
-}
-
-@end
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item_unittest.mm
deleted file mode 100644
index a162162..0000000
--- a/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item_unittest.mm
+++ /dev/null
@@ -1,101 +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.
-
-#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-using LegacySyncSwitchItemTest = PlatformTest;
-
-// Tests that the text label and showing status are set properly after a call to
-// |configureCell:|.
-TEST_F(LegacySyncSwitchItemTest, ConfigureCell) {
-  LegacySyncSwitchItem* item = [[LegacySyncSwitchItem alloc] initWithType:0];
-  LegacySyncSwitchCell* cell = [[[item cellClass] alloc] init];
-  EXPECT_TRUE([cell isMemberOfClass:[LegacySyncSwitchCell class]]);
-  EXPECT_NSEQ(nil, cell.textLabel.text);
-
-  NSString* text = @"Test Switch";
-  NSString* detailText = @"Test Switch Detail";
-
-  item.text = text;
-  item.detailText = detailText;
-  item.on = YES;
-
-  EXPECT_FALSE(cell.textLabel.text);
-  EXPECT_FALSE(cell.detailTextLabel.text);
-  EXPECT_FALSE(cell.switchView.isOn);
-
-  [item configureCell:cell];
-  EXPECT_NSEQ(text, cell.textLabel.text);
-  EXPECT_NSEQ(detailText, cell.detailTextLabel.text);
-  EXPECT_TRUE(cell.switchView.isOn);
-}
-
-}  // namespace
-
-// Tests that the text color and enabled state of the switch are set correctly
-// by a call to |configureCell:|.
-TEST_F(LegacySyncSwitchItemTest, EnabledAndDisabled) {
-  LegacySyncSwitchCell* cell = [[LegacySyncSwitchCell alloc] init];
-  LegacySyncSwitchItem* item = [[LegacySyncSwitchItem alloc] initWithType:0];
-  item.text = @"Test Switch";
-
-  // Text color possibilities.
-  UIColor* enabledColor =
-      [LegacySyncSwitchCell defaultTextColorForState:UIControlStateNormal];
-  UIColor* disabledColor =
-      [LegacySyncSwitchCell defaultTextColorForState:UIControlStateDisabled];
-
-  // Enabled and off.
-  item.on = NO;
-  item.enabled = YES;
-  [item configureCell:cell];
-  EXPECT_FALSE(cell.switchView.isOn);
-  EXPECT_NSEQ(enabledColor, cell.textLabel.textColor);
-
-  // Enabled and on.
-  item.on = YES;
-  item.enabled = YES;
-  [item configureCell:cell];
-  EXPECT_TRUE(cell.switchView.isOn);
-  EXPECT_NSEQ(enabledColor, cell.textLabel.textColor);
-
-  // Disabled and off.
-  item.on = NO;
-  item.enabled = NO;
-  [item configureCell:cell];
-  EXPECT_FALSE(cell.switchView.isOn);
-  EXPECT_NSEQ(disabledColor, cell.textLabel.textColor);
-
-  // Disabled and on. Disabling shouldn't change the switch's on value.
-  item.on = YES;
-  item.enabled = NO;
-  [item configureCell:cell];
-  EXPECT_TRUE(cell.switchView.isOn);
-  EXPECT_NSEQ(disabledColor, cell.textLabel.textColor);
-}
-
-TEST_F(LegacySyncSwitchItemTest, PrepareForReuseClearsActions) {
-  LegacySyncSwitchCell* cell = [[LegacySyncSwitchCell alloc] init];
-  UISwitch* switchView = cell.switchView;
-  NSArray* target = [NSArray array];
-
-  EXPECT_EQ(0U, [[switchView allTargets] count]);
-  [switchView addTarget:target
-                 action:@selector(count)
-       forControlEvents:UIControlEventValueChanged];
-  EXPECT_EQ(1U, [[switchView allTargets] count]);
-
-  [cell prepareForReuse];
-  EXPECT_EQ(0U, [[switchView allTargets] count]);
-}
diff --git a/ios/chrome/browser/ui/settings/cells/text_and_error_item.h b/ios/chrome/browser/ui/settings/cells/text_and_error_item.h
deleted file mode 100644
index 9b47db86..0000000
--- a/ios/chrome/browser/ui/settings/cells/text_and_error_item.h
+++ /dev/null
@@ -1,43 +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 IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_TEXT_AND_ERROR_ITEM_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_TEXT_AND_ERROR_ITEM_H_
-
-#import <UIKit/UIKit.h>
-
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
-
-// TextAndErrorItem: Displays a text label and might containg an accessory type.
-// It might also display an error icon at the right side of the cell if the
-// shouldDisplayError flag is set to true.
-// TODO(crbug.com/894800): Remove this.
-@interface TextAndErrorItem : CollectionViewItem
-
-// Item text.
-@property(nonatomic, copy) NSString* text;
-
-// Boolean to display or hide the error icon.
-@property(nonatomic, assign) BOOL shouldDisplayError;
-
-// The accessory type for the represented cell.
-@property(nonatomic) MDCCollectionViewCellAccessoryType accessoryType;
-
-// Whether or not the item is enabled.
-@property(nonatomic, assign, getter=isEnabled) BOOL enabled;
-
-@end
-
-@interface TextAndErrorCell : MDCCollectionViewCell
-
-// Cell title.
-@property(nonatomic, readonly, strong) UILabel* textLabel;
-
-// Error icon that will be displayed on the right side of the cell.
-@property(nonatomic, readonly, strong) UIImageView* errorIcon;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_TEXT_AND_ERROR_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/text_and_error_item.mm b/ios/chrome/browser/ui/settings/cells/text_and_error_item.mm
deleted file mode 100644
index 2faa628..0000000
--- a/ios/chrome/browser/ui/settings/cells/text_and_error_item.mm
+++ /dev/null
@@ -1,167 +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.
-
-#import "ios/chrome/browser/ui/settings/cells/text_and_error_item.h"
-
-#include "base/mac/foundation_util.h"
-#include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
-#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
-#import "ios/chrome/common/ui_util/constraints_ui_util.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
-#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-// Padding used on the leading and trailing edges of the cell.
-const CGFloat kHorizontalPadding = 16;
-
-// Padding used on the top and bottom edges of the cell.
-const CGFloat kVerticalPadding = 16;
-
-// Padding used between the image and text.
-const CGFloat kHorizontalPaddingBetweenImageAndText = 10;
-
-// Error icon fixed horizontal size.
-const CGFloat kHorizontalErrorIconFixedSize = 25;
-}  // namespace
-
-@implementation TextAndErrorItem
-
-@synthesize text = _text;
-@synthesize accessoryType = _accessoryType;
-@synthesize shouldDisplayError = _shouldDisplayError;
-@synthesize enabled = _enabled;
-
-- (instancetype)initWithType:(NSInteger)type {
-  self = [super initWithType:type];
-  if (self) {
-    self.cellClass = [TextAndErrorCell class];
-    self.accessibilityTraits |= UIAccessibilityTraitButton;
-    self.enabled = YES;
-  }
-  return self;
-}
-
-- (void)configureCell:(TextAndErrorCell*)cell {
-  [super configureCell:cell];
-  cell.textLabel.text = self.text;
-  cell.accessoryType = self.accessoryType;
-  cell.accessibilityLabel = self.text;
-  if (self.shouldDisplayError) {
-    cell.errorIcon.image = [UIImage imageNamed:@"settings_error"];
-  } else {
-    cell.errorIcon.image = nil;
-  }
-  UIImageView* accessoryImage =
-      base::mac::ObjCCastStrict<UIImageView>(cell.accessoryView);
-  accessoryImage.image = [accessoryImage.image
-      imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
-  if (self.isEnabled) {
-    cell.textLabel.textColor = [[MDCPalette greyPalette] tint900];
-    [cell setUserInteractionEnabled:YES];
-    [accessoryImage setTintColor:[[MDCPalette greyPalette] tint400]];
-  } else {
-    [accessoryImage setTintColor:[[[MDCPalette greyPalette] tint200]
-                                     colorWithAlphaComponent:0.5]];
-    cell.textLabel.textColor = [[MDCPalette greyPalette] tint500];
-    [cell setUserInteractionEnabled:NO];
-  }
-}
-
-@end
-
-@interface TextAndErrorCell () {
-  // Constraint used to set the errorIcon width depending on its existence.
-  NSLayoutConstraint* _errorIconWidthConstraint;
-}
-
-@end
-
-@implementation TextAndErrorCell
-
-@synthesize textLabel = _textLabel;
-@synthesize errorIcon = _errorIcon;
-
-- (instancetype)initWithFrame:(CGRect)frame {
-  self = [super initWithFrame:frame];
-  if (self) {
-    self.contentView.clipsToBounds = YES;
-    _textLabel = [[UILabel alloc] init];
-    _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
-    _textLabel.font = [UIFont systemFontOfSize:kUIKitMainFontSize];
-    _textLabel.textColor = UIColorFromRGB(kUIKitMainTextColor);
-    _textLabel.numberOfLines = 0;
-    [self.contentView addSubview:_textLabel];
-    _errorIcon = [[UIImageView alloc] init];
-    _errorIcon.translatesAutoresizingMaskIntoConstraints = NO;
-    [self.contentView addSubview:_errorIcon];
-
-    [self setConstraints];
-  }
-  return self;
-}
-
-- (void)setConstraints {
-  UIView* contentView = self.contentView;
-
-  _errorIconWidthConstraint = [_errorIcon.widthAnchor
-      constraintEqualToConstant:kHorizontalErrorIconFixedSize];
-
-  [NSLayoutConstraint activateConstraints:@[
-    [_textLabel.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor
-                                             constant:kHorizontalPadding],
-    [_textLabel.trailingAnchor
-        constraintEqualToAnchor:_errorIcon.leadingAnchor
-                       constant:-kHorizontalPaddingBetweenImageAndText],
-    [_errorIcon.trailingAnchor
-        constraintEqualToAnchor:contentView.trailingAnchor
-                       constant:-kHorizontalPadding],
-    [_errorIcon.centerYAnchor
-        constraintEqualToAnchor:contentView.centerYAnchor],
-    _errorIconWidthConstraint,
-  ]];
-
-  AddOptionalVerticalPadding(contentView, _textLabel, kVerticalPadding);
-}
-
-// Implement -layoutSubviews as per instructions in documentation for
-// +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:].
-- (void)layoutSubviews {
-  [super layoutSubviews];
-
-  // Adjust the text and detailText label preferredMaxLayoutWidth when the
-  // parent's width
-  // changes, for instance on screen rotation.
-  if (_errorIcon.image) {
-    _errorIconWidthConstraint.constant = kHorizontalErrorIconFixedSize;
-    _textLabel.preferredMaxLayoutWidth =
-        CGRectGetWidth(self.contentView.frame) -
-        CGRectGetWidth(_errorIcon.frame) - 2 * kHorizontalPadding -
-        kHorizontalPaddingBetweenImageAndText;
-  } else {
-    _errorIconWidthConstraint.constant = 0;
-    _textLabel.preferredMaxLayoutWidth =
-        CGRectGetWidth(self.contentView.frame) - 2 * kHorizontalPadding;
-  }
-
-  // Re-layout with the new preferred width to allow the label to adjust its
-  // height.
-  [super layoutSubviews];
-}
-
-- (void)prepareForReuse {
-  [super prepareForReuse];
-  self.textLabel.textColor = [[MDCPalette greyPalette] tint900];
-  [self setUserInteractionEnabled:YES];
-  UIImageView* accessoryImage =
-      base::mac::ObjCCastStrict<UIImageView>(self.accessoryView);
-  accessoryImage.image = [accessoryImage.image
-      imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
-  [accessoryImage setTintColor:[[MDCPalette greyPalette] tint400]];
-}
-
-@end
diff --git a/ios/chrome/browser/ui/settings/cells/text_and_error_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/text_and_error_item_unittest.mm
deleted file mode 100644
index e4cdf8c..0000000
--- a/ios/chrome/browser/ui/settings/cells/text_and_error_item_unittest.mm
+++ /dev/null
@@ -1,55 +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.
-
-#import "ios/chrome/browser/ui/settings/cells/text_and_error_item.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-using TextAndErrorItemTest = PlatformTest;
-
-// Tests that the error UIImage and UILabels are set properly after a call to
-// |configureCell:|.
-TEST_F(TextAndErrorItemTest, ImageViewAndLabels) {
-  TextAndErrorItem* item = [[TextAndErrorItem alloc] initWithType:0];
-  item.text = @"Test";
-  item.shouldDisplayError = YES;
-  item.enabled = YES;
-
-  // Text color options.
-  UIColor* enabledColor = [[MDCPalette greyPalette] tint900];
-  UIColor* disabledColor = [[MDCPalette greyPalette] tint500];
-
-  id cell = [[[item cellClass] alloc] init];
-  ASSERT_TRUE([cell isMemberOfClass:[TextAndErrorCell class]]);
-
-  TextAndErrorCell* signInCell = cell;
-  EXPECT_FALSE(signInCell.errorIcon.image);
-  EXPECT_FALSE(signInCell.textLabel.text);
-
-  [item configureCell:cell];
-  EXPECT_TRUE(signInCell.errorIcon.image);
-  EXPECT_NSEQ(item.text, signInCell.textLabel.text);
-  EXPECT_NSEQ(enabledColor, signInCell.textLabel.textColor);
-
-  item.shouldDisplayError = NO;
-
-  [item configureCell:cell];
-  EXPECT_FALSE(signInCell.errorIcon.image);
-  EXPECT_NSEQ(item.text, signInCell.textLabel.text);
-
-  item.enabled = NO;
-  [item configureCell:cell];
-  EXPECT_NSEQ(disabledColor, signInCell.textLabel.textColor);
-}
-
-}  // namespace
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
index c384c08c..312f137c 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
@@ -28,7 +28,6 @@
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
 #include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
index b00c4a4..7d68699a 100644
--- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -11,7 +11,6 @@
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/grit/components_scaled_resources.h"
 #import "ios/chrome/browser/ui/authentication/cells/legacy_account_control_item.h"
-#import "ios/chrome/browser/ui/authentication/cells/signin_promo_item.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_delegate.h"
 #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h"
@@ -31,7 +30,6 @@
 #import "ios/chrome/browser/ui/payments/cells/payments_text_item.h"
 #import "ios/chrome/browser/ui/payments/cells/price_item.h"
 #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h"
-#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h"
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.h"
 #import "ios/chrome/browser/ui/settings/cells/passphrase_error_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_multiline_detail_item.h"
@@ -83,8 +81,6 @@
   ItemTypeAccountDetail,
   ItemTypeAccountCheckMark,
   ItemTypeAccountSignIn,
-  ItemTypeColdStateSigninPromo,
-  ItemTypeWarmStateSigninPromo,
   ItemTypeApp,
   ItemTypePaymentsSingleLine,
   ItemTypePaymentsDynamicHeight,
@@ -293,10 +289,6 @@
       toSectionWithIdentifier:SectionIdentifierAccountCell];
   [model addItem:[self accountItemCheckMark]
       toSectionWithIdentifier:SectionIdentifierAccountCell];
-  [model addItem:[self coldStateSigninPromoItem]
-      toSectionWithIdentifier:SectionIdentifierAccountCell];
-  [model addItem:[self warmStateSigninPromoItem]
-      toSectionWithIdentifier:SectionIdentifierAccountCell];
 
   // Account control cells.
   [model addSectionWithIdentifier:SectionIdentifierAccountControlCell];
@@ -345,8 +337,6 @@
     case ItemTypeAutofillStatus:
     case ItemTypePaymentsDynamicHeight:
     case ItemTypeAutofillDynamicHeight:
-    case ItemTypeColdStateSigninPromo:
-    case ItemTypeWarmStateSigninPromo:
       return [MDCCollectionViewCell
           cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
                              forItem:item];
@@ -402,9 +392,7 @@
       [self.collectionViewModel itemAtIndexPath:indexPath];
   switch (item.type) {
     case ItemTypeApp:
-    case ItemTypeColdStateSigninPromo:
     case ItemTypeSwitchDynamicHeight:
-    case ItemTypeWarmStateSigninPromo:
       return YES;
     default:
       return NO;
@@ -446,28 +434,6 @@
   return accountItemCheckMark;
 }
 
-- (CollectionViewItem*)coldStateSigninPromoItem {
-  SigninPromoItem* signinPromoItem =
-      [[SigninPromoItem alloc] initWithType:ItemTypeWarmStateSigninPromo];
-  signinPromoItem.configurator =
-      [[SigninPromoViewConfigurator alloc] initWithUserEmail:nil
-                                                userFullName:nil
-                                                   userImage:nil
-                                              hasCloseButton:YES];
-  return signinPromoItem;
-}
-
-- (CollectionViewItem*)warmStateSigninPromoItem {
-  SigninPromoItem* signinPromoItem =
-      [[SigninPromoItem alloc] initWithType:ItemTypeColdStateSigninPromo];
-  signinPromoItem.configurator = [[SigninPromoViewConfigurator alloc]
-      initWithUserEmail:@"jonhdoe@example.com"
-           userFullName:@"John Doe"
-              userImage:nil
-         hasCloseButton:NO];
-  return signinPromoItem;
-}
-
 - (CollectionViewItem*)accountControlItem {
   LegacyAccountControlItem* item = [[LegacyAccountControlItem alloc]
       initWithType:ItemTypeAccountControlDynamicHeight];
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
index 22d59f8..5c49556 100644
--- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
@@ -156,6 +156,13 @@
     [self.navigationController setToolbarHidden:YES animated:YES];
 }
 
+- (void)viewDidLayoutSubviews {
+  [super viewDidLayoutSubviews];
+  // TODO(crbug.com/931173): This is a workaround to fix the vertical alignment
+  // of the back button. Remove once the UIKit bug is fixed.
+  [self.navigationController.navigationBar setNeedsLayout];
+}
+
 #pragma mark - UITableViewDelegate
 
 - (void)tableView:(UITableView*)tableView
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn
index bb4f959f..f62f74a9 100644
--- a/ios/chrome/test/BUILD.gn
+++ b/ios/chrome/test/BUILD.gn
@@ -227,7 +227,6 @@
     "//ios/chrome/browser/ui/settings:unit_tests",
     "//ios/chrome/browser/ui/settings/autofill:unit_tests",
     "//ios/chrome/browser/ui/settings/cells:unit_tests",
-    "//ios/chrome/browser/ui/settings/cells/legacy:unit_tests",
     "//ios/chrome/browser/ui/settings/clear_browsing_data:unit_tests",
     "//ios/chrome/browser/ui/settings/password:unit_tests",
     "//ios/chrome/browser/ui/settings/sync:unit_tests",
diff --git a/ios/web/DEPS b/ios/web/DEPS
index cf49397..da771b4ce 100644
--- a/ios/web/DEPS
+++ b/ios/web/DEPS
@@ -17,5 +17,7 @@
   # For tests.
   "+ios/testing",
   "+ios/third_party/earl_grey/src",
+  "+ios/third_party/earl_grey2/src/CommonLib",
+  "+ios/third_party/earl_grey2/src/TestLib",
   "+mojo/core/embedder/embedder.h",
 ]
diff --git a/ios/web/shell/test/BUILD.gn b/ios/web/shell/test/BUILD.gn
index 3e7b195b..71b437e5 100644
--- a/ios/web/shell/test/BUILD.gn
+++ b/ios/web/shell/test/BUILD.gn
@@ -4,11 +4,14 @@
 
 import("//ios/build/config.gni")
 import("//ios/third_party/earl_grey/ios_eg_test.gni")
+import("//ios/third_party/earl_grey2/ios_eg2_test.gni")
 
 group("all_tests") {
   testonly = true
   deps = [
+    ":ios_web_shell_eg2tests",
     ":ios_web_shell_egtests",
+    ":ios_web_shell_test_app_host",
   ]
 }
 
@@ -104,3 +107,56 @@
         "{{source_file_part}}",
   ]
 }
+
+################################
+# EG2 targets.
+
+group("eg_app_support+eg2") {
+  testonly = true
+}
+
+group("eg_test_support+eg2") {
+  testonly = true
+}
+
+source_set("eg_tests+eg2") {
+  configs += [
+    "//build/config/compiler:enable_arc",
+    "//build/config/ios:xctest_config",
+  ]
+  testonly = true
+
+  sources = [
+    "web_shell_egtest.mm",
+  ]
+
+  include_dirs = [ "//ios/third_party/edo/src" ]
+
+  deps = [
+    ":eg_test_support+eg2",
+    "//ios/third_party/earl_grey2:test_lib",
+  ]
+
+  libs = [ "UIKit.framework" ]
+}
+
+ios_eg2_test_app_host("ios_web_shell_test_app_host") {
+  info_plist = "//ios/web/shell/Info.plist"
+
+  deps = [
+    "//ios/web/shell",
+
+    # Test support libraries.
+    ":eg_app_support+eg2",
+    "//ios/testing/earl_grey:eg_app_support+eg2",
+  ]
+}
+
+ios_eg2_test("ios_web_shell_eg2tests") {
+  xcode_test_application_name = "ios_web_shell_test_app_host"
+
+  deps = [
+    # Test support libraries.
+    ":eg_tests+eg2",
+  ]
+}
diff --git a/ios/web/shell/test/web_shell_egtest.mm b/ios/web/shell/test/web_shell_egtest.mm
new file mode 100644
index 0000000..6b29000
--- /dev/null
+++ b/ios/web/shell/test/web_shell_egtest.mm
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <UIKit/UIKit.h>
+#import <XCTest/XCTest.h>
+
+#import "ios/third_party/earl_grey2/src/TestLib/EarlGreyImpl/EarlGrey.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+// WebShellTestCase will temporarily hold EG2 versions of web shell tests, until
+// the EG2 tests are running on the bots and the EG1 versions can be deleted.
+@interface WebShellTestCase : XCTestCase
+@end
+
+@implementation WebShellTestCase
+
+- (void)setUp {
+  [super setUp];
+  static dispatch_once_t onceToken;
+  dispatch_once(&onceToken, ^{
+    XCUIApplication* application = [[XCUIApplication alloc] init];
+    [application launch];
+  });
+}
+
+@end
diff --git a/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.mm b/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.mm
index 4ae0ca5f..d666651 100644
--- a/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.mm
+++ b/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.mm
@@ -65,7 +65,7 @@
       profile_db, account_db, browser_state->GetPrefs(),
       WebViewIdentityManagerFactory::GetForBrowserState(browser_state),
       /*client_profile_validator=*/nullptr, /*history_service=*/nullptr,
-      /*gaia_cookie_manager_service=*/nullptr, browser_state->IsOffTheRecord());
+      browser_state->IsOffTheRecord());
   return service;
 }
 
diff --git a/media/midi/midi_manager_alsa.cc b/media/midi/midi_manager_alsa.cc
index b13df63d..361d960 100644
--- a/media/midi/midi_manager_alsa.cc
+++ b/media/midi/midi_manager_alsa.cc
@@ -169,17 +169,18 @@
     // because of SND_SEQ_EVENT_CLIENT_EXIT.
     out_client_.reset();
   }
-
   // Ensure that no task is running any more.
-  bool result = service()->task_service()->UnbindInstance();
-  CHECK(result);
+  if (!service()->task_service()->UnbindInstance())
+    return;
+
+  // |out_client_| should be reset before UnbindInstance() call to avoid
+  // a deadlock, but other finalization steps should be implemented after the
+  // UnbindInstance() call above, if we need.
 }
 
 void MidiManagerAlsa::StartInitialization() {
-  if (!service()->task_service()->BindInstance()) {
-    NOTREACHED();
+  if (!service()->task_service()->BindInstance())
     return CompleteInitialization(Result::INITIALIZATION_ERROR);
-  }
 
   // Create client handles and name the clients.
   int err;
diff --git a/media/midi/midi_manager_android.cc b/media/midi/midi_manager_android.cc
index a7ddeca..5f6500a 100644
--- a/media/midi/midi_manager_android.cc
+++ b/media/midi/midi_manager_android.cc
@@ -51,18 +51,17 @@
     : MidiManager(service) {}
 
 MidiManagerAndroid::~MidiManagerAndroid() {
+  if (!service()->task_service()->UnbindInstance())
+    return;
+
+  // Finalization steps should be implemented after the UnbindInstance() call.
   JNIEnv* env = base::android::AttachCurrentThread();
   Java_MidiManagerAndroid_stop(env, raw_manager_);
-  bool result = service()->task_service()->UnbindInstance();
-  CHECK(result);
 }
 
 void MidiManagerAndroid::StartInitialization() {
-  if (!service()->task_service()->BindInstance()) {
-    NOTREACHED();
-    CompleteInitialization(Result::INITIALIZATION_ERROR);
-    return;
-  }
+  if (!service()->task_service()->BindInstance())
+    return CompleteInitialization(Result::INITIALIZATION_ERROR);
 
   JNIEnv* env = base::android::AttachCurrentThread();
 
diff --git a/media/midi/midi_manager_mac.cc b/media/midi/midi_manager_mac.cc
index 96fdf9c7..6041adc 100644
--- a/media/midi/midi_manager_mac.cc
+++ b/media/midi/midi_manager_mac.cc
@@ -118,9 +118,10 @@
 MidiManagerMac::MidiManagerMac(MidiService* service) : MidiManager(service) {}
 
 MidiManagerMac::~MidiManagerMac() {
-  bool result = service()->task_service()->UnbindInstance();
-  CHECK(result);
+  if (!service()->task_service()->UnbindInstance())
+    return;
 
+  // Finalization steps should be implemented after the UnbindInstance() call.
   // Do not need to dispose |coremidi_input_| and |coremidi_output_| explicitly.
   // CoreMIDI automatically disposes them on the client disposal.
   base::AutoLock lock(midi_client_lock_);
@@ -129,10 +130,9 @@
 }
 
 void MidiManagerMac::StartInitialization() {
-  if (!service()->task_service()->BindInstance()) {
-    NOTREACHED();
+  if (!service()->task_service()->BindInstance())
     return CompleteInitialization(Result::INITIALIZATION_ERROR);
-  }
+
   service()->task_service()->PostBoundTask(
       kClientTaskRunner, base::BindOnce(&MidiManagerMac::InitializeCoreMIDI,
                                         base::Unretained(this)));
diff --git a/media/midi/midi_manager_unittest.cc b/media/midi/midi_manager_unittest.cc
index 8bf2362..d7bceb1 100644
--- a/media/midi/midi_manager_unittest.cc
+++ b/media/midi/midi_manager_unittest.cc
@@ -19,8 +19,13 @@
 #include "base/test/scoped_task_environment.h"
 #include "build/build_config.h"
 #include "media/midi/midi_service.h"
+#include "media/midi/task_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if defined(OS_WIN)
+#include "media/midi/midi_manager_win.h"
+#endif  // defined(OS_WIN)
+
 namespace midi {
 
 namespace {
@@ -315,40 +320,79 @@
   run_loop.RunUntilIdle();
 }
 
+class PlatformMidiManagerTest : public ::testing::Test {
+ public:
+  PlatformMidiManagerTest()
+      : client_(std::make_unique<FakeMidiManagerClient>()),
+        service_(std::make_unique<MidiService>()) {
+    //
+  }
+
+  ~PlatformMidiManagerTest() override {
+    service_->Shutdown();
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
+
+  MidiService* service() { return service_.get(); }
+
+  void StartSession() { service_->StartSession(client_.get()); }
+  void EndSession() { service_->EndSession(client_.get()); }
+  Result WaitForResult() { return client_->WaitForResult(); }
+
+  // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc.
+  // Do not change the condition for disabling this test.
+  bool IsSupported() {
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && \
+    !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID)
+    return false;
+#else
+    return true;
+#endif
+  }
+
+ private:
+  // SystemMonitor is needed on Windows.
+  base::SystemMonitor system_monitor;
+
+  base::test::ScopedTaskEnvironment env_;
+
+  std::unique_ptr<FakeMidiManagerClient> client_;
+  std::unique_ptr<MidiService> service_;
+
+  DISALLOW_COPY_AND_ASSIGN(PlatformMidiManagerTest);
+};
+
 #if defined(OS_ANDROID)
 // The test sometimes fails on Android. https://crbug.com/844027
 #define MAYBE_CreatePlatformMidiManager DISABLED_CreatePlatformMidiManager
 #else
 #define MAYBE_CreatePlatformMidiManager CreatePlatformMidiManager
 #endif
-TEST_F(MidiManagerTest, MAYBE_CreatePlatformMidiManager) {
-  // SystemMonitor is needed on Windows.
-  base::SystemMonitor system_monitor;
+TEST_F(PlatformMidiManagerTest, MAYBE_CreatePlatformMidiManager) {
+  StartSession();
+  Result result = WaitForResult();
 
-  std::unique_ptr<FakeMidiManagerClient> client =
-      std::make_unique<FakeMidiManagerClient>();
-
-  // Use own MidiService instance to construct a real platform dependent
-  // MidiManager instance.
-  std::unique_ptr<MidiService> service = std::make_unique<MidiService>();
-  service->StartSession(client.get());
-
-  Result result = client->WaitForResult();
-  // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc.
-  // Do not change the condition for disabling this test.
-#if !defined(OS_MACOSX) && !defined(OS_WIN) && \
-    !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID)
-  EXPECT_EQ(Result::NOT_SUPPORTED, result);
-#elif defined(USE_ALSA)
+#if defined(USE_ALSA)
   // Temporary until http://crbug.com/371230 is resolved.
   EXPECT_TRUE(result == Result::OK || result == Result::INITIALIZATION_ERROR);
 #else
-  EXPECT_EQ(Result::OK, result);
+  EXPECT_EQ(IsSupported() ? Result::OK : Result::NOT_SUPPORTED, result);
 #endif
+}
 
-  service->Shutdown();
-  base::RunLoop run_loop;
-  run_loop.RunUntilIdle();
+TEST_F(PlatformMidiManagerTest, InstanceIdOverflow) {
+  service()->task_service()->OverflowInstanceIdForTesting();
+#if defined(OS_WIN)
+  MidiManagerWin::OverflowInstanceIdForTesting();
+#endif  // defined(OS_WIN)
+
+  StartSession();
+  EXPECT_EQ(
+      IsSupported() ? Result::INITIALIZATION_ERROR : Result::NOT_SUPPORTED,
+      WaitForResult());
+
+  EndSession();
 }
 
 }  // namespace
diff --git a/media/midi/midi_manager_usb.cc b/media/midi/midi_manager_usb.cc
index fc6421e2..d57f374d 100644
--- a/media/midi/midi_manager_usb.cc
+++ b/media/midi/midi_manager_usb.cc
@@ -24,16 +24,16 @@
     : MidiManager(service), device_factory_(std::move(factory)) {}
 
 MidiManagerUsb::~MidiManagerUsb() {
-  bool result = service()->task_service()->UnbindInstance();
-  CHECK(result);
+  if (!service()->task_service()->UnbindInstance())
+    return;
+
+  // Finalization steps should be implemented after the UnbindInstance() call
+  // above, if we need.
 }
 
 void MidiManagerUsb::StartInitialization() {
-  if (!service()->task_service()->BindInstance()) {
-    NOTREACHED();
-    CompleteInitialization(Result::INITIALIZATION_ERROR);
-    return;
-  }
+  if (!service()->task_service()->BindInstance())
+    return CompleteInitialization(Result::INITIALIZATION_ERROR);
 
   Initialize();
 }
diff --git a/media/midi/midi_manager_win.cc b/media/midi/midi_manager_win.cc
index 50c61670..e543077 100644
--- a/media/midi/midi_manager_win.cc
+++ b/media/midi/midi_manager_win.cc
@@ -12,12 +12,14 @@
 #include <mmsystem.h>
 
 #include <algorithm>
+#include <limits>
 #include <string>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/logging.h"
+#include "base/optional.h"
 #include "base/single_thread_task_runner.h"
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
@@ -104,8 +106,8 @@
 constexpr size_t kBufferLength = 32 * 1024;
 
 // Global variables to identify MidiManager instance.
-constexpr int kInvalidInstanceId = -1;
-int g_active_instance_id = kInvalidInstanceId;
+constexpr int64_t kInvalidInstanceId = -1;
+int64_t g_active_instance_id = kInvalidInstanceId;
 MidiManagerWin* g_manager_instance = nullptr;
 
 // Obtains base::Lock instance pointer to lock instance_id.
@@ -115,8 +117,15 @@
 }
 
 // Issues unique MidiManager instance ID.
-int IssueNextInstanceId() {
-  static int id = kInvalidInstanceId;
+int64_t IssueNextInstanceId(base::Optional<int64_t> override_id) {
+  static int64_t id = kInvalidInstanceId;
+  if (override_id) {
+    int64_t result = ++id;
+    id = *override_id;
+    return result;
+  }
+  if (id == std::numeric_limits<int64_t>::max())
+    return kInvalidInstanceId;
   return ++id;
 }
 
@@ -687,9 +696,14 @@
   }
 }
 
+// static
+void MidiManagerWin::OverflowInstanceIdForTesting() {
+  IssueNextInstanceId(std::numeric_limits<int64_t>::max());
+}
+
 MidiManagerWin::MidiManagerWin(MidiService* service)
     : MidiManager(service),
-      instance_id_(IssueNextInstanceId()),
+      instance_id_(IssueNextInstanceId(base::nullopt)),
       port_manager_(std::make_unique<PortManager>()) {
   base::AutoLock lock(*GetInstanceIdLock());
   CHECK_EQ(kInvalidInstanceId, g_active_instance_id);
@@ -699,6 +713,11 @@
 }
 
 MidiManagerWin::~MidiManagerWin() {
+  // Initialization failed. Exit without running actual finalization that should
+  // not be needed.
+  if (instance_id_ == kInvalidInstanceId)
+    return;
+
   // Unregisters on the I/O thread. OnDevicesChanged() won't be called any more.
   CHECK(thread_runner_->BelongsToCurrentThread());
   base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this);
@@ -733,6 +752,9 @@
 void MidiManagerWin::StartInitialization() {
   {
     base::AutoLock lock(*GetInstanceIdLock());
+    if (instance_id_ == kInvalidInstanceId)
+      return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR);
+
     CHECK_EQ(kInvalidInstanceId, g_active_instance_id);
     g_active_instance_id = instance_id_;
     CHECK_EQ(nullptr, g_manager_instance);
diff --git a/media/midi/midi_manager_win.h b/media/midi/midi_manager_win.h
index 3516a14..978abfac 100644
--- a/media/midi/midi_manager_win.h
+++ b/media/midi/midi_manager_win.h
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/system/system_monitor.h"
+#include "media/midi/midi_export.h"
 #include "media/midi/midi_manager.h"
 
 namespace base {
@@ -28,6 +29,8 @@
  public:
   class PortManager;
 
+  MIDI_EXPORT static void OverflowInstanceIdForTesting();
+
   explicit MidiManagerWin(MidiService* service);
   ~MidiManagerWin() override;
 
@@ -83,7 +86,7 @@
                         const std::vector<uint8_t>& data);
 
   // Holds an unique instance ID.
-  const int instance_id_;
+  const int64_t instance_id_;
 
   // Keeps a TaskRunner for the I/O thread.
   scoped_refptr<base::SingleThreadTaskRunner> thread_runner_;
diff --git a/media/midi/midi_manager_winrt.cc b/media/midi/midi_manager_winrt.cc
index c1310aa0..4c0fded 100644
--- a/media/midi/midi_manager_winrt.cc
+++ b/media/midi/midi_manager_winrt.cc
@@ -777,8 +777,8 @@
 MidiManagerWinrt::~MidiManagerWinrt() {
   // Unbind and take a lock to ensure that InitializeOnComRunner should not run
   // after here.
-  bool result = service()->task_service()->UnbindInstance();
-  CHECK(result);
+  if (!service()->task_service()->UnbindInstance())
+    return;
 
   base::AutoLock auto_lock(lazy_init_member_lock_);
   service()->task_service()->PostStaticTask(
@@ -788,11 +788,8 @@
 }
 
 void MidiManagerWinrt::StartInitialization() {
-  if (!service()->task_service()->BindInstance()) {
-    NOTREACHED();
-    CompleteInitialization(Result::INITIALIZATION_ERROR);
-    return;
-  }
+  if (!service()->task_service()->BindInstance())
+    return CompleteInitialization(Result::INITIALIZATION_ERROR);
 
   service()->task_service()->PostBoundTask(
       kComTaskRunner, base::BindOnce(&MidiManagerWinrt::InitializeOnComRunner,
diff --git a/media/midi/task_service.cc b/media/midi/task_service.cc
index ed245d28..4ba79ddb 100644
--- a/media/midi/task_service.cc
+++ b/media/midi/task_service.cc
@@ -4,6 +4,8 @@
 
 #include "media/midi/task_service.h"
 
+#include <limits>
+
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/stringprintf.h"
@@ -13,19 +15,10 @@
 
 namespace midi {
 
-namespace {
-
-constexpr TaskService::InstanceId kInvalidInstanceId = -1;
-
-}  // namespace
-
 constexpr TaskService::RunnerId TaskService::kDefaultRunnerId;
+constexpr TaskService::InstanceId TaskService::kInvalidInstanceId;
 
-TaskService::TaskService()
-    : no_tasks_in_flight_cv_(&tasks_in_flight_lock_),
-      tasks_in_flight_(0),
-      next_instance_id_(0),
-      bound_instance_id_(kInvalidInstanceId) {
+TaskService::TaskService() : no_tasks_in_flight_cv_(&tasks_in_flight_lock_) {
   DETACH_FROM_SEQUENCE(instance_binding_sequence_checker_);
 }
 
@@ -46,10 +39,17 @@
   base::AutoLock lock(lock_);
   if (bound_instance_id_ != kInvalidInstanceId)
     return false;
-  bound_instance_id_ = next_instance_id_++;
+
+  // If the InstanceId reaches to the limit, just fail rather than doing
+  // something nicer for such impractical case.
+  if (std::numeric_limits<InstanceId>::max() == next_instance_id_)
+    return false;
+
+  bound_instance_id_ = ++next_instance_id_;
 
   DCHECK(!default_task_runner_);
   default_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+
   return true;
 }
 
@@ -59,16 +59,17 @@
     base::AutoLock lock(lock_);
     if (bound_instance_id_ == kInvalidInstanceId)
       return false;
+
+    DCHECK_EQ(next_instance_id_, bound_instance_id_);
     bound_instance_id_ = kInvalidInstanceId;
 
     DCHECK(default_task_runner_);
     default_task_runner_ = nullptr;
   }
-
   // From now on RunTask will never run any task bound to the instance id.
   // But invoked tasks might be still running here. To ensure no task runs on
   // quitting this method, wait for all tasks to complete.
-  base::AutoLock tasks_in_flight_auto_lock(tasks_in_flight_lock_);
+  base::AutoLock tasks_in_flight_lock(tasks_in_flight_lock_);
   // TODO(https://crbug.com/796830): Remove sync operations on the I/O thread.
   base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
   while (tasks_in_flight_ > 0)
@@ -127,6 +128,10 @@
       delay);
 }
 
+void TaskService::OverflowInstanceIdForTesting() {
+  next_instance_id_ = std::numeric_limits<InstanceId>::max();
+}
+
 scoped_refptr<base::SingleThreadTaskRunner> TaskService::GetTaskRunner(
     RunnerId runner_id) {
   base::AutoLock lock(lock_);
@@ -155,7 +160,7 @@
                           RunnerId runner_id,
                           base::OnceClosure task) {
   {
-    base::AutoLock tasks_in_flight_auto_lock(tasks_in_flight_lock_);
+    base::AutoLock tasks_in_flight_lock(tasks_in_flight_lock_);
     ++tasks_in_flight_;
   }
 
@@ -163,7 +168,7 @@
     std::move(task).Run();
 
   {
-    base::AutoLock tasks_in_flight_auto_lock(tasks_in_flight_lock_);
+    base::AutoLock tasks_in_flight_lock(tasks_in_flight_lock_);
     --tasks_in_flight_;
     DCHECK_GE(tasks_in_flight_, 0);
     if (tasks_in_flight_ == 0)
diff --git a/media/midi/task_service.h b/media/midi/task_service.h
index 2e19b2c..3ac8f31f 100644
--- a/media/midi/task_service.h
+++ b/media/midi/task_service.h
@@ -5,13 +5,18 @@
 #ifndef MEDIA_MIDI_TASK_SERVICE_H_
 #define MEDIA_MIDI_TASK_SERVICE_H_
 
+#include <memory>
+#include <vector>
+
 #include "base/callback_forward.h"
+#include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequence_checker.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
 #include "base/threading/thread.h"
 #include "base/time/time.h"
 #include "media/midi/midi_export.h"
@@ -23,7 +28,7 @@
 class MIDI_EXPORT TaskService final {
  public:
   using RunnerId = size_t;
-  using InstanceId = int;
+  using InstanceId = int64_t;
 
   static constexpr RunnerId kDefaultRunnerId = 0;
 
@@ -36,9 +41,10 @@
   // invoked any more.
   // Returns true if call is bound or unbound correctly. Otherwise returns
   // false, that happens when the BindInstance() is called twice without
-  // unbinding the previous instance.
-  bool BindInstance();
-  bool UnbindInstance();
+  // unbinding the previous instance, or the UnbindInstance() is called without
+  // any successful BindInstance() call.
+  bool BindInstance() WARN_UNUSED_RESULT;
+  bool UnbindInstance() WARN_UNUSED_RESULT;
 
   // Checks if the current thread belongs to the specified runner.
   bool IsOnTaskRunner(RunnerId runner_id);
@@ -58,7 +64,11 @@
                             base::OnceClosure task,
                             base::TimeDelta delay);
 
+  void OverflowInstanceIdForTesting();
+
  private:
+  static constexpr TaskService::InstanceId kInvalidInstanceId = -1;
+
   // Returns a SingleThreadTaskRunner reference. Each TaskRunner will be
   // constructed on demand.
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(RunnerId runner_id);
@@ -71,31 +81,32 @@
   // Returns true if |instance_id| is equal to |bound_instance_id_|.
   bool IsInstanceIdStillBound(InstanceId instance_id);
 
+  // Holds InstanceId for the next bound instance, accessed on the BindInstance
+  // call thread without any protection.
+  InstanceId next_instance_id_ = kInvalidInstanceId;
+
   // Keeps a TaskRunner for the thread that calls BindInstance() as a default
   // task runner to run posted tasks.
-  scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_
+      GUARDED_BY(lock_);
 
   // Holds threads to host SingleThreadTaskRunners.
-  std::vector<std::unique_ptr<base::Thread>> threads_;
+  std::vector<std::unique_ptr<base::Thread>> threads_ GUARDED_BY(lock_);
 
-  // Protects |tasks_in_flight_|.
-  base::Lock tasks_in_flight_lock_;
+  // Holds InstanceId for the current bound instance.
+  InstanceId bound_instance_id_ GUARDED_BY(lock_) = kInvalidInstanceId;
+
+  base::Lock lock_;
 
   // Signalled when the number of tasks in flight is 0 and ensures that
   // UnbindInstance() does not return until all tasks have completed.
-  base::ConditionVariable no_tasks_in_flight_cv_;
+  base::ConditionVariable no_tasks_in_flight_cv_
+      GUARDED_BY(tasks_in_flight_lock_);
 
   // Number of tasks in flight.
-  int tasks_in_flight_;
+  int tasks_in_flight_ GUARDED_BY(tasks_in_flight_lock_) = 0;
 
-  // Holds InstanceId for the next bound instance.
-  InstanceId next_instance_id_;
-
-  // Holds InstanceId for the current bound instance.
-  InstanceId bound_instance_id_;
-
-  // Protects all members other than |tasks_in_flight_|.
-  base::Lock lock_;
+  base::Lock tasks_in_flight_lock_;
 
   // Verifies all UnbindInstance() calls occur on the same sequence as
   // BindInstance().
diff --git a/remoting/ios/app/remoting_theme.mm b/remoting/ios/app/remoting_theme.mm
index 0f8d6ba..9c315bf 100644
--- a/remoting/ios/app/remoting_theme.mm
+++ b/remoting/ios/app/remoting_theme.mm
@@ -19,7 +19,12 @@
 + (void)applyColorSchemes {
   MDCBasicColorScheme* colorScheme = [[MDCBasicColorScheme alloc]
       initWithPrimaryColor:RemotingTheme.flatButtonTextColor];
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  // TODO(crbug.com/930714): +[MDCAlertColorThemer applyColorScheme:] is
+  // deprecated. Needs to be replaced.
   [MDCAlertColorThemer applyColorScheme:colorScheme];
+#pragma GCC diagnostic pop
 }
 
 #pragma mark - Colors
diff --git a/services/identity/BUILD.gn b/services/identity/BUILD.gn
index ba278ece2..cae93bb 100644
--- a/services/identity/BUILD.gn
+++ b/services/identity/BUILD.gn
@@ -36,7 +36,6 @@
     "//components/prefs:test_support",
     "//components/signin/core/browser:internals",
     "//components/signin/core/browser:internals_test_support",
-    "//components/signin/core/browser:internals_test_support",
     "//components/signin/core/browser:shared",
     "//components/sync_preferences:test_support",
     "//mojo/public/cpp/bindings",
diff --git a/services/identity/public/cpp/BUILD.gn b/services/identity/public/cpp/BUILD.gn
index b92c284..206fe3e 100644
--- a/services/identity/public/cpp/BUILD.gn
+++ b/services/identity/public/cpp/BUILD.gn
@@ -84,6 +84,7 @@
 source_set("tests") {
   testonly = true
   sources = [
+    "accounts_cookie_mutator_unittest.cc",
     "accounts_mutator_unittest.cc",
     "primary_account_mutator_unittest.cc",
   ]
@@ -93,6 +94,8 @@
     ":test_support",
     "//base",
     "//base/test:test_support",
+    "//components/signin/core/browser:internals_test_support",
+    "//services/network:test_support",
     "//testing/gtest",
   ]
 }
diff --git a/services/identity/public/cpp/DEPS b/services/identity/public/cpp/DEPS
index 9b5dac39..93030af 100644
--- a/services/identity/public/cpp/DEPS
+++ b/services/identity/public/cpp/DEPS
@@ -24,6 +24,12 @@
     "+google_apis/gaia/oauth2_token_service_delegate.h",
     "+services/network/test/test_url_loader_factory.h",
   ],
+  "accounts_cookie_mutator_unittest.cc" : [
+    "+google_apis/gaia/gaia_constants.h",
+    "+google_apis/gaia/gaia_urls.h",
+    "+services/network/test/test_url_loader_factory.h",
+    "+services/network/test/test_utils.h",
+  ],
   "identity_manager_unittest.cc": [
     "+google_apis/gaia/oauth2_token_service_delegate.h",
     "+services/network/test/test_cookie_manager.h",
diff --git a/services/identity/public/cpp/accounts_cookie_mutator.h b/services/identity/public/cpp/accounts_cookie_mutator.h
index 7094270c..d2020be1 100644
--- a/services/identity/public/cpp/accounts_cookie_mutator.h
+++ b/services/identity/public/cpp/accounts_cookie_mutator.h
@@ -5,7 +5,11 @@
 #ifndef SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_COOKIE_MUTATOR_H_
 #define SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_COOKIE_MUTATOR_H_
 
+#include <string>
+
 #include "base/macros.h"
+#include "google_apis/gaia/gaia_auth_fetcher.h"
+#include "google_apis/gaia/google_service_auth_error.h"
 
 namespace identity {
 
@@ -16,6 +20,30 @@
   AccountsCookieMutator() = default;
   virtual ~AccountsCookieMutator() = default;
 
+  // Adds an account identified by |account_id| to the cookie responsible for
+  // tracking the list of logged-in Google sessions across the web.
+  virtual void AddAccountToCookie(const std::string& account_id,
+                                  gaia::GaiaSource source) = 0;
+
+  // Adds an account identified by |account_id| and with |access_token| to the
+  // cookie responsible for tracking the list of logged-in Google sessions
+  // across the web.
+  virtual void AddAccountToCookieWithToken(const std::string& account_id,
+                                           const std::string& access_token,
+                                           gaia::GaiaSource source) = 0;
+
+  // Triggers a ListAccounts fetch. Can be used in circumstances where clients
+  // know that the contents of the Gaia cookie might have changed.
+  virtual void TriggerCookieJarUpdate() = 0;
+
+  // Notifies observers that |account_id| has been added to the Gaia cookie.
+  // Should only be invoked manually in cases where clients have detected that
+  // an account is in the Gaia cookie and want to ensure that observers are
+  // notified.
+  virtual void ForceTriggerOnAddAccountToCookieCompleted(
+      const std::string& account_id,
+      const GoogleServiceAuthError& error) = 0;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(AccountsCookieMutator);
 };
diff --git a/services/identity/public/cpp/accounts_cookie_mutator_impl.cc b/services/identity/public/cpp/accounts_cookie_mutator_impl.cc
index 160ba59..ce6c0d85c 100644
--- a/services/identity/public/cpp/accounts_cookie_mutator_impl.cc
+++ b/services/identity/public/cpp/accounts_cookie_mutator_impl.cc
@@ -16,4 +16,28 @@
 
 AccountsCookieMutatorImpl::~AccountsCookieMutatorImpl() {}
 
+void AccountsCookieMutatorImpl::AddAccountToCookie(
+    const std::string& account_id,
+    gaia::GaiaSource source) {
+  gaia_cookie_manager_service_->AddAccountToCookie(account_id, source);
+}
+
+void AccountsCookieMutatorImpl::AddAccountToCookieWithToken(
+    const std::string& account_id,
+    const std::string& access_token,
+    gaia::GaiaSource source) {
+  gaia_cookie_manager_service_->AddAccountToCookieWithToken(
+      account_id, access_token, source);
+}
+
+void AccountsCookieMutatorImpl::TriggerCookieJarUpdate() {
+  gaia_cookie_manager_service_->TriggerListAccounts();
+}
+
+void AccountsCookieMutatorImpl::ForceTriggerOnAddAccountToCookieCompleted(
+    const std::string& account_id,
+    const GoogleServiceAuthError& error) {
+  gaia_cookie_manager_service_->SignalComplete(account_id, error);
+}
+
 }  // namespace identity
diff --git a/services/identity/public/cpp/accounts_cookie_mutator_impl.h b/services/identity/public/cpp/accounts_cookie_mutator_impl.h
index c358d26..a9ee7db8 100644
--- a/services/identity/public/cpp/accounts_cookie_mutator_impl.h
+++ b/services/identity/public/cpp/accounts_cookie_mutator_impl.h
@@ -5,10 +5,17 @@
 #ifndef SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_COOKIE_MUTATOR_IMPL_H_
 #define SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_COOKIE_MUTATOR_IMPL_H_
 
+#include <string>
+
 #include "base/macros.h"
 #include "services/identity/public/cpp/accounts_cookie_mutator.h"
 
 class GaiaCookieManagerService;
+class GoogleServiceAuthError;
+
+namespace gaia {
+enum class GaiaSource;
+}
 
 namespace identity {
 
@@ -19,6 +26,19 @@
       GaiaCookieManagerService* gaia_cookie_manager_service);
   ~AccountsCookieMutatorImpl() override;
 
+  void AddAccountToCookie(const std::string& account_id,
+                          gaia::GaiaSource source) override;
+
+  void AddAccountToCookieWithToken(const std::string& account_id,
+                                   const std::string& access_token,
+                                   gaia::GaiaSource source) override;
+
+  void TriggerCookieJarUpdate() override;
+
+  void ForceTriggerOnAddAccountToCookieCompleted(
+      const std::string& account_id,
+      const GoogleServiceAuthError& error) override;
+
  private:
   GaiaCookieManagerService* gaia_cookie_manager_service_;
 
diff --git a/services/identity/public/cpp/accounts_cookie_mutator_unittest.cc b/services/identity/public/cpp/accounts_cookie_mutator_unittest.cc
new file mode 100644
index 0000000..f0bcf55b
--- /dev/null
+++ b/services/identity/public/cpp/accounts_cookie_mutator_unittest.cc
@@ -0,0 +1,343 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/identity/public/cpp/accounts_cookie_mutator.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "base/test/gtest_util.h"
+#include "base/test/scoped_task_environment.h"
+#include "components/signin/core/browser/list_accounts_test_utils.h"
+#include "google_apis/gaia/gaia_auth_fetcher.h"
+#include "google_apis/gaia/gaia_constants.h"
+#include "google_apis/gaia/gaia_urls.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "services/identity/public/cpp/accounts_in_cookie_jar_info.h"
+#include "services/identity/public/cpp/identity_manager.h"
+#include "services/identity/public/cpp/identity_test_environment.h"
+#include "services/network/test/test_url_loader_factory.h"
+#include "services/network/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kTestUnavailableAccountId[] = "unavailable_account_id";
+const char kTestAccountEmail[] = "test_user@test.com";
+const char kTestAccountGaiaId[] = "gaia_id_for_test_user_test.com";
+const char kTestAccessToken[] = "access_token";
+const char kTestUberToken[] = "test_uber_token";
+
+enum class AccountsCookiesMutatorAction {
+  kAddAccountToCookie,
+  kTriggerCookieJarUpdateNoAccounts,
+  kTriggerCookieJarUpdateOneAccount,
+};
+
+// Class that observes updates from identity::IdentityManager.
+class TestIdentityManagerObserver : public identity::IdentityManager::Observer {
+ public:
+  explicit TestIdentityManagerObserver(
+      identity::IdentityManager* identity_manager)
+      : identity_manager_(identity_manager) {
+    identity_manager_->AddObserver(this);
+  }
+  ~TestIdentityManagerObserver() override {
+    identity_manager_->RemoveObserver(this);
+  }
+
+  void set_on_accounts_in_cookie_updated_callback(
+      base::OnceCallback<void(const identity::AccountsInCookieJarInfo&,
+                              const GoogleServiceAuthError&)> callback) {
+    on_accounts_in_cookie_updated_callback_ = std::move(callback);
+  }
+
+  void set_on_add_account_to_cookie_completed_callback(
+      base::OnceCallback<void(const std::string&,
+                              const GoogleServiceAuthError&)> callback) {
+    on_add_account_to_cookie_completed_callback_ = std::move(callback);
+  }
+
+ private:
+  // identity::IdentityManager::Observer:
+  void OnAccountsInCookieUpdated(
+      const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
+      const GoogleServiceAuthError& error) override {
+    if (on_accounts_in_cookie_updated_callback_)
+      std::move(on_accounts_in_cookie_updated_callback_)
+          .Run(accounts_in_cookie_jar_info, error);
+  }
+
+  void OnAddAccountToCookieCompleted(
+      const std::string& account_id,
+      const GoogleServiceAuthError& error) override {
+    if (on_add_account_to_cookie_completed_callback_)
+      std::move(on_add_account_to_cookie_completed_callback_)
+          .Run(account_id, error);
+  }
+
+  identity::IdentityManager* identity_manager_;
+  base::OnceCallback<void(const identity::AccountsInCookieJarInfo&,
+                          const GoogleServiceAuthError&)>
+      on_accounts_in_cookie_updated_callback_;
+  base::OnceCallback<void(const std::string&, const GoogleServiceAuthError&)>
+      on_add_account_to_cookie_completed_callback_;
+};
+
+}  // namespace
+
+namespace identity {
+class AccountsCookieMutatorTest : public testing::Test {
+ public:
+  AccountsCookieMutatorTest()
+      : identity_test_env_(&test_url_loader_factory_),
+        identity_manager_observer_(identity_test_env_.identity_manager()) {}
+
+  ~AccountsCookieMutatorTest() override {}
+
+  // Make an account available and returns the account ID.
+  std::string AddAcountWithRefreshToken(const std::string& email) {
+    return identity_test_env_.MakeAccountAvailable(email).account_id;
+  }
+
+  // Feed the TestURLLoaderFactory with the responses for the requests that will
+  // be created by UberTokenFetcher when mergin accounts into the cookie jar.
+  void PrepareURLLoaderResponsesForAction(AccountsCookiesMutatorAction action) {
+    switch (action) {
+      case AccountsCookiesMutatorAction::kAddAccountToCookie:
+        test_url_loader_factory_.AddResponse(
+            GaiaUrls::GetInstance()
+                ->oauth1_login_url()
+                .Resolve(base::StringPrintf("?source=%s&issueuberauth=1",
+                                            GaiaConstants::kChromeSource))
+                .spec(),
+            kTestUberToken, net::HTTP_OK);
+
+        test_url_loader_factory_.AddResponse(
+            GaiaUrls::GetInstance()
+                ->GetCheckConnectionInfoURLWithSource(
+                    GaiaConstants::kChromeSource)
+                .spec(),
+            std::string(), net::HTTP_OK);
+
+        test_url_loader_factory_.AddResponse(
+            GaiaUrls::GetInstance()
+                ->merge_session_url()
+                .Resolve(base::StringPrintf(
+                    "?uberauth=%s&continue=http://www.google.com&source=%s",
+                    kTestUberToken, GaiaConstants::kChromeSource))
+                .spec(),
+            std::string(), net::HTTP_OK);
+        break;
+      case AccountsCookiesMutatorAction::kTriggerCookieJarUpdateNoAccounts:
+        signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
+        break;
+      case AccountsCookiesMutatorAction::kTriggerCookieJarUpdateOneAccount:
+        signin::SetListAccountsResponseOneAccount(
+            kTestAccountEmail, kTestAccountGaiaId, &test_url_loader_factory_);
+        break;
+    }
+  }
+
+  identity::IdentityTestEnvironment* identity_test_env() {
+    return &identity_test_env_;
+  }
+
+  TestIdentityManagerObserver* identity_manager_observer() {
+    return &identity_manager_observer_;
+  }
+
+  AccountsCookieMutator* accounts_cookie_mutator() {
+    return identity_test_env_.identity_manager()->GetAccountsCookieMutator();
+  }
+
+ private:
+  base::test::ScopedTaskEnvironment task_environment_;
+  network::TestURLLoaderFactory test_url_loader_factory_;
+  identity::IdentityTestEnvironment identity_test_env_;
+  TestIdentityManagerObserver identity_manager_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(AccountsCookieMutatorTest);
+};
+
+// Test that adding a non existing account without providing an access token
+// results in an error due to such account not being available.
+TEST_F(AccountsCookieMutatorTest, AddAccountToCookie_NonExistingAccount) {
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_add_account_to_cookie_completed_callback(
+      base::BindOnce(
+          [](base::OnceClosure quit_closure, const std::string& account_id,
+             const GoogleServiceAuthError& error) {
+            EXPECT_EQ(account_id, kTestUnavailableAccountId);
+            // The account was not previously available and no access token was
+            // provided when adding it to the cookie jar: expect an error.
+            EXPECT_EQ(error.state(),
+                      GoogleServiceAuthError::USER_NOT_SIGNED_UP);
+            std::move(quit_closure).Run();
+          },
+          run_loop.QuitClosure()));
+
+  accounts_cookie_mutator()->AddAccountToCookie(kTestUnavailableAccountId,
+                                                gaia::GaiaSource::kChrome);
+  run_loop.Run();
+}
+
+// Test that adding an already available account without providing an access
+// token results in such account being successfully merged into the cookie jar.
+TEST_F(AccountsCookieMutatorTest, AddAccountToCookie_ExistingAccount) {
+  PrepareURLLoaderResponsesForAction(
+      AccountsCookiesMutatorAction::kAddAccountToCookie);
+
+  std::string account_id = AddAcountWithRefreshToken(kTestAccountEmail);
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_add_account_to_cookie_completed_callback(
+      base::BindOnce(
+          [](base::OnceClosure quit_closure,
+             const std::string& expected_account_id,
+             const std::string& account_id,
+             const GoogleServiceAuthError& error) {
+            EXPECT_EQ(account_id, expected_account_id);
+            // The account was previously available: expect success.
+            EXPECT_EQ(error.state(), GoogleServiceAuthError::NONE);
+            std::move(quit_closure).Run();
+          },
+          run_loop.QuitClosure(), account_id));
+
+  accounts_cookie_mutator()->AddAccountToCookie(account_id,
+                                                gaia::GaiaSource::kChrome);
+  identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+      account_id, kTestAccessToken,
+      base::Time::Now() + base::TimeDelta::FromHours(1));
+
+  run_loop.Run();
+}
+
+// Test that adding a non existing account along with an access token, results
+// on such account being successfully merged into the cookie jar.
+TEST_F(AccountsCookieMutatorTest,
+       AddAccountToCookieWithAccessToken_NonExistingAccount) {
+  PrepareURLLoaderResponsesForAction(
+      AccountsCookiesMutatorAction::kAddAccountToCookie);
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_add_account_to_cookie_completed_callback(
+      base::BindOnce(
+          [](base::OnceClosure quit_closure, const std::string& account_id,
+             const GoogleServiceAuthError& error) {
+            EXPECT_EQ(account_id, kTestUnavailableAccountId);
+            // Trying to add an non-available account with a valid token to the
+            // cookie jar should result in the account being merged.
+            EXPECT_EQ(error.state(), GoogleServiceAuthError::NONE);
+            std::move(quit_closure).Run();
+          },
+          run_loop.QuitClosure()));
+
+  accounts_cookie_mutator()->AddAccountToCookieWithToken(
+      kTestUnavailableAccountId, kTestAccessToken, gaia::GaiaSource::kChrome);
+  run_loop.Run();
+}
+
+// Test that adding an already available account along with an access token,
+// results in such account being successfully merged into the cookie jar.
+TEST_F(AccountsCookieMutatorTest,
+       AddAccountToCookieWithAccessToken_ExistingAccount) {
+  PrepareURLLoaderResponsesForAction(
+      AccountsCookiesMutatorAction::kAddAccountToCookie);
+
+  std::string account_id = AddAcountWithRefreshToken(kTestAccountEmail);
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_add_account_to_cookie_completed_callback(
+      base::BindOnce(
+          [](base::OnceClosure quit_closure,
+             const std::string& expected_account_id,
+             const std::string& account_id,
+             const GoogleServiceAuthError& error) {
+            EXPECT_EQ(account_id, expected_account_id);
+            // Trying to add a previously available account with a valid token
+            // to the cookie jar should also result in the account being merged.
+            EXPECT_EQ(error.state(), GoogleServiceAuthError::NONE);
+            std::move(quit_closure).Run();
+          },
+          run_loop.QuitClosure(), account_id));
+
+  accounts_cookie_mutator()->AddAccountToCookieWithToken(
+      account_id, kTestAccessToken, gaia::GaiaSource::kChrome);
+
+  run_loop.Run();
+}
+
+// Test triggering the update of a cookie jar with no accounts works.
+TEST_F(AccountsCookieMutatorTest, TriggerCookieJarUpdate_NoListedAccounts) {
+  PrepareURLLoaderResponsesForAction(
+      AccountsCookiesMutatorAction::kTriggerCookieJarUpdateNoAccounts);
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+      base::BindOnce(
+          [](base::OnceClosure quit_closure,
+             const identity::AccountsInCookieJarInfo& accounts_in_jar_info,
+             const GoogleServiceAuthError& error) {
+            EXPECT_EQ(accounts_in_jar_info.signed_in_accounts.size(), 0U);
+            EXPECT_EQ(accounts_in_jar_info.signed_out_accounts.size(), 0U);
+            EXPECT_TRUE(accounts_in_jar_info.accounts_are_fresh);
+            EXPECT_EQ(error.state(), GoogleServiceAuthError::NONE);
+            std::move(quit_closure).Run();
+          },
+          run_loop.QuitClosure()));
+
+  accounts_cookie_mutator()->TriggerCookieJarUpdate();
+  run_loop.Run();
+}
+
+// Test triggering the update of a cookie jar with one accounts works and that
+// the received accounts match the data injected via the TestURLLoaderFactory.
+TEST_F(AccountsCookieMutatorTest, TriggerCookieJarUpdate_OneListedAccounts) {
+  PrepareURLLoaderResponsesForAction(
+      AccountsCookiesMutatorAction::kTriggerCookieJarUpdateOneAccount);
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+      base::BindOnce(
+          [](base::OnceClosure quit_closure,
+             const identity::AccountsInCookieJarInfo& accounts_in_jar_info,
+             const GoogleServiceAuthError& error) {
+            EXPECT_EQ(accounts_in_jar_info.signed_in_accounts.size(), 1U);
+            EXPECT_EQ(accounts_in_jar_info.signed_in_accounts[0].gaia_id,
+                      kTestAccountGaiaId);
+            EXPECT_EQ(accounts_in_jar_info.signed_in_accounts[0].email,
+                      kTestAccountEmail);
+
+            EXPECT_EQ(accounts_in_jar_info.signed_out_accounts.size(), 0U);
+            EXPECT_TRUE(accounts_in_jar_info.accounts_are_fresh);
+            EXPECT_EQ(error.state(), GoogleServiceAuthError::NONE);
+            std::move(quit_closure).Run();
+          },
+          run_loop.QuitClosure()));
+
+  accounts_cookie_mutator()->TriggerCookieJarUpdate();
+  run_loop.Run();
+}
+
+// Test that calling ForceTriggerOnAddAccountToCookieCompleted() with an account
+// ID and a valid error runs the callback with that data passed through.
+TEST_F(AccountsCookieMutatorTest, ForceTriggerOnAddAccountToCookieCompleted) {
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_add_account_to_cookie_completed_callback(
+      base::BindOnce(
+          [](base::OnceClosure quit_closure, const std::string& account_id,
+             const GoogleServiceAuthError& error) {
+            EXPECT_EQ(account_id, kTestUnavailableAccountId);
+            EXPECT_EQ(error.state(), GoogleServiceAuthError::TWO_FACTOR);
+            std::move(quit_closure).Run();
+          },
+          run_loop.QuitClosure()));
+
+  accounts_cookie_mutator()->ForceTriggerOnAddAccountToCookieCompleted(
+      kTestUnavailableAccountId,
+      GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR));
+  run_loop.Run();
+}
+
+}  // namespace identity
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h
index bdd3ccb..1ffeb8fb 100644
--- a/services/identity/public/cpp/identity_manager.h
+++ b/services/identity/public/cpp/identity_manager.h
@@ -421,6 +421,9 @@
                                            const std::string& account_id);
   friend void UpdateAccountInfoForAccount(IdentityManager* identity_manager,
                                           AccountInfo account_info);
+  friend void SetFreshnessOfAccountsInGaiaCookie(
+      IdentityManager* identity_manager,
+      bool accounts_are_fresh);
   friend void UpdatePersistentErrorOfRefreshTokenForAccount(
       IdentityManager* identity_manager,
       const std::string& account_id,
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc
index 898c0aa7..040bb85 100644
--- a/services/identity/public/cpp/identity_test_environment.cc
+++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -513,8 +513,8 @@
 
 void IdentityTestEnvironment::SetFreshnessOfAccountsInGaiaCookie(
     bool accounts_are_fresh) {
-  gaia_cookie_manager_service_->set_list_accounts_stale_for_testing(
-      accounts_are_fresh);
+  identity::SetFreshnessOfAccountsInGaiaCookie(identity_manager(),
+                                               accounts_are_fresh);
 }
 
 void IdentityTestEnvironment::
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc
index e13c7a5..8ea39df 100644
--- a/services/identity/public/cpp/identity_test_utils.cc
+++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -390,6 +390,13 @@
   account_tracker_service->SeedAccountInfo(account_info);
 }
 
+void SetFreshnessOfAccountsInGaiaCookie(IdentityManager* identity_manager,
+                                        bool accounts_are_fresh) {
+  GaiaCookieManagerService* cookie_manager =
+      identity_manager->GetGaiaCookieManagerService();
+  cookie_manager->set_list_accounts_stale_for_testing(!accounts_are_fresh);
+}
+
 std::string GetTestGaiaIdForEmail(const std::string& email) {
   std::string gaia_id =
       std::string("gaia_id_for_") + gaia::CanonicalizeEmail(email);
diff --git a/services/identity/public/cpp/identity_test_utils.h b/services/identity/public/cpp/identity_test_utils.h
index 71772edf..b69186a0 100644
--- a/services/identity/public/cpp/identity_test_utils.h
+++ b/services/identity/public/cpp/identity_test_utils.h
@@ -134,6 +134,11 @@
 void UpdateAccountInfoForAccount(IdentityManager* identity_manager,
                                  AccountInfo account_info);
 
+// Sets whether the list of accounts in Gaia cookie jar is fresh and does not
+// need to be updated.
+void SetFreshnessOfAccountsInGaiaCookie(IdentityManager* identity_manager,
+                                        bool accounts_are_fresh);
+
 std::string GetTestGaiaIdForEmail(const std::string& email);
 
 // Updates the persistent auth error set on |account_id| which must be a known
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
index 6d5525c6..9a8ead3 100644
--- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
+++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -130,16 +130,11 @@
  public:
   ThreadLocalEventSink(
       std::unique_ptr<perfetto::StartupTraceWriter> trace_writer,
-      perfetto::BufferID target_buffer,
+      uint32_t session_id,
       bool thread_will_flush)
       : trace_writer_(std::move(trace_writer)),
-        target_buffer_(target_buffer),
-        thread_will_flush_(thread_will_flush) {
-#if DCHECK_IS_ON()
-    static std::atomic<int32_t> id_counter(1);
-    sink_id_ = id_counter.fetch_add(1, std::memory_order_relaxed);
-#endif  // DCHECK_IS_ON()
-  }
+        session_id_(session_id),
+        thread_will_flush_(thread_will_flush) {}
 
   ~ThreadLocalEventSink() {
     // Finalize the current message before posting the |trace_writer_| for
@@ -220,13 +215,10 @@
         return;
       }
 
-#if DCHECK_IS_ON()
-      handle->chunk_seq = sink_id_;
-#endif  // DCHECK_IS_ON()
-
       complete_event_stack_[current_stack_depth_] = std::move(*trace_event);
       handle->event_index = ++current_stack_depth_;
       handle->chunk_index = kMagicChunkIndex;
+      handle->chunk_seq = session_id_;
       return;
     }
 
@@ -401,14 +393,11 @@
   void UpdateDuration(base::trace_event::TraceEventHandle handle,
                       const base::TimeTicks& now,
                       const base::ThreadTicks& thread_now) {
-    if (!handle.event_index || handle.chunk_index != kMagicChunkIndex) {
+    if (!handle.event_index || handle.chunk_index != kMagicChunkIndex ||
+        handle.chunk_seq != session_id_) {
       return;
     }
 
-#if DCHECK_IS_ON()
-    DCHECK_EQ(handle.chunk_seq, sink_id_);
-#endif  // DCHECK_IS_ON()
-
     DCHECK_EQ(handle.event_index, current_stack_depth_);
     DCHECK_GE(current_stack_depth_, 1u);
     current_stack_depth_--;
@@ -434,11 +423,11 @@
     trace_writer_->Flush();
   }
 
-  perfetto::BufferID target_buffer() const { return target_buffer_; }
+  uint32_t session_id() const { return session_id_; }
 
  private:
   std::unique_ptr<perfetto::StartupTraceWriter> trace_writer_;
-  perfetto::BufferID target_buffer_;
+  uint32_t session_id_;
   const bool thread_will_flush_;
   ChromeEventBundleHandle event_bundle_;
   perfetto::TraceWriter::TracePacketHandle trace_packet_handle_;
@@ -447,9 +436,6 @@
   size_t current_eventcount_for_message_ = 0;
   TraceEvent complete_event_stack_[kMaxCompleteEventDepth];
   uint32_t current_stack_depth_ = 0;
-#if DCHECK_IS_ON()
-  uint32_t sink_id_;
-#endif  // DCHECK_IS_ON()
 };
 
 namespace {
@@ -509,12 +495,13 @@
 
     DCHECK(!producer_client_);
     producer_client_ = producer_client;
-    target_buffer_.store(data_source_config.target_buffer(),
-                         std::memory_order_relaxed);
+    target_buffer_ = data_source_config.target_buffer();
     // Reduce lock contention by binding the registry without holding the lock.
     unbound_writer_registry = std::move(startup_writer_registry_);
   }
 
+  session_id_.fetch_add(1u, std::memory_order_relaxed);
+
   if (unbound_writer_registry) {
     producer_client->BindStartupTraceWriterRegistry(
         std::move(unbound_writer_registry), data_source_config.target_buffer());
@@ -558,7 +545,7 @@
     base::AutoLock lock(lock_);
     DCHECK(producer_client_);
     producer_client_ = nullptr;
-    target_buffer_.store(0, std::memory_order_relaxed);
+    target_buffer_ = 0;
   }
 
   if (was_enabled) {
@@ -635,13 +622,12 @@
   if (startup_writer_registry_) {
     return new ThreadLocalEventSink(
         startup_writer_registry_->CreateUnboundTraceWriter(),
-        target_buffer_.load(std::memory_order_relaxed), thread_will_flush);
+        session_id_.load(std::memory_order_relaxed), thread_will_flush);
   } else if (producer_client_) {
     return new ThreadLocalEventSink(
         std::make_unique<perfetto::StartupTraceWriter>(
-            producer_client_->CreateTraceWriter(
-                target_buffer_.load(std::memory_order_relaxed))),
-        target_buffer_.load(std::memory_order_relaxed), thread_will_flush);
+            producer_client_->CreateTraceWriter(target_buffer_)),
+        session_id_.load(std::memory_order_relaxed), thread_will_flush);
   } else {
     return nullptr;
   }
@@ -660,17 +646,25 @@
   // been reset if the current thread doesn't support flushing. In that case, we
   // need to check here that it writes to the right buffer.
   //
-  // Because we want to avoid locking for each event, we access |target_buffer_|
-  // racily. It's OK if we don't see it change to the new buffer immediately. In
+  // Because we want to avoid locking for each event, we access |session_id_|
+  // racily. It's OK if we don't see it change to the session immediately. In
   // that case, the first few trace events may get lost, but we will eventually
   // notice that we are writing to the wrong buffer once the change to
-  // |target_buffer_| has propagated, and reset the sink. Note we will still
+  // |session_id_| has propagated, and reset the sink. Note we will still
   // acquire the |lock_| to safely recreate the sink in
   // CreateThreadLocalEventSink().
-  if (!thread_will_flush && thread_local_event_sink &&
-      GetInstance()->target_buffer_.load(std::memory_order_relaxed) !=
-          thread_local_event_sink->target_buffer()) {
-    thread_local_event_sink = nullptr;
+  if (!thread_will_flush && thread_local_event_sink) {
+    uint32_t new_session_id =
+        GetInstance()->session_id_.load(std::memory_order_relaxed);
+    // Ignore the first session to avoid resetting the sink during startup
+    // tracing, where the sink is created with kInvalidSessionID. Resetting the
+    // sink during startup might cause data buffered in its potentially still
+    // unbound StartupTraceWriter to be lost.
+    if (new_session_id > kFirstSessionID &&
+        new_session_id != thread_local_event_sink->session_id()) {
+      delete thread_local_event_sink;
+      thread_local_event_sink = nullptr;
+    }
   }
 
   if (!thread_local_event_sink) {
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.h b/services/tracing/public/cpp/perfetto/trace_event_data_source.h
index b627427..6f0e4d5 100644
--- a/services/tracing/public/cpp/perfetto/trace_event_data_source.h
+++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.h
@@ -5,6 +5,7 @@
 #ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACE_EVENT_DATA_SOURCE_H_
 #define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACE_EVENT_DATA_SOURCE_H_
 
+#include <atomic>
 #include <memory>
 #include <string>
 #include <vector>
@@ -120,12 +121,14 @@
 
   base::OnceClosure stop_complete_callback_;
 
+  // Incremented and accessed atomically but without memory order guarantees.
+  // This ID is incremented whenever a new tracing session is started.
+  static constexpr uint32_t kInvalidSessionID = 0;
+  static constexpr uint32_t kFirstSessionID = 1;
+  std::atomic<uint32_t> session_id_{kInvalidSessionID};
+
   base::Lock lock_;  // Protects subsequent members.
-  // Regular accesses to |target_buffer_| in conjunction with other fields are
-  // protected by |lock_|, thus no memory order guarantees are required when
-  // writing or reading it in those places. Note that OnAddTraceEvent()
-  // accesses its atomic value racily without holding |lock_|.
-  std::atomic<uint32_t> target_buffer_{0};
+  uint32_t target_buffer_ = 0;
   ProducerClient* producer_client_ = nullptr;
   // We own the registry during startup, but transfer its ownership to the
   // ProducerClient once the perfetto service is available. Only set if
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
index e2a5eff..a740034 100644
--- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
+++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -603,6 +603,8 @@
   EXPECT_EQ(new_events.size(), 1);
 }
 
+// TODO(eseckler): Add startup tracing unittests.
+
 }  // namespace
 
 }  // namespace tracing
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index b6e23e29..4bca2fe2 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1283,6 +1283,25 @@
             ]
         }
     ],
+    "CompressParkableStringsInForeground": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "CompressParkableStringsInForeground"
+                    ]
+                }
+            ]
+        }
+    ],
     "ContextualSearch": [
         {
             "platforms": [
@@ -4337,6 +4356,26 @@
             ]
         }
     ],
+    "ServiceWorkerForegroundPriority": [
+        {
+            "platforms": [
+                "android",
+                "android_webview",
+                "chromeos",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "ServiceWorkerForegroundPriority"
+                    ]
+                }
+            ]
+        }
+    ],
     "ServiceWorkerServicification": [
         {
             "platforms": [
diff --git a/third_party/android_crazy_linker/BUILD.gn b/third_party/android_crazy_linker/BUILD.gn
index 36001497..135c1e7 100644
--- a/third_party/android_crazy_linker/BUILD.gn
+++ b/third_party/android_crazy_linker/BUILD.gn
@@ -31,7 +31,6 @@
       ":crazy_linker_test_dl_wrappers_valid_handles",
       ":crazy_linker_test_dl_wrappers_with_system_handle",
       ":crazy_linker_test_load_library",
-      ":crazy_linker_test_load_library_callbacks",
       ":crazy_linker_test_load_library_depends",
       ":crazy_linker_test_load_library_with_gnu_hash_table",
       ":crazy_linker_test_load_library_with_relr_relocations",
@@ -383,19 +382,6 @@
     ]
   }
 
-  executable("crazy_linker_test_load_library_callbacks") {
-    sources = [
-      "src/tests/test_load_library_callbacks.cpp",
-    ]
-    include_dirs = [ "src/src" ]  # Needed for crazy_linker_util_threads.h
-    data_deps = [
-      ":crazy_linker_tests_libbar",
-    ]
-    deps = [
-      ":android_crazy_linker",
-    ]
-  }
-
   executable("crazy_linker_test_constructors_destructors") {
     sources = [
       "src/tests/test_constructors_destructors.cpp",
diff --git a/third_party/android_crazy_linker/src/include/crazy_linker.h b/third_party/android_crazy_linker/src/include/crazy_linker.h
index 2f619813..3afaed68 100644
--- a/third_party/android_crazy_linker/src/include/crazy_linker.h
+++ b/third_party/android_crazy_linker/src/include/crazy_linker.h
@@ -131,71 +131,6 @@
 // Destroy a given context object.
 void crazy_context_destroy(crazy_context_t* context) _CRAZY_PUBLIC;
 
-// Some operations performed by the crazy linker might conflict with the
-// system linker if they are used concurrently in different threads
-// (e.g. modifying the list of shared libraries seen by GDB). To work
-// around this, the crazy linker provides a way to delay these conflicting
-// operations for a later time.
-//
-// This works by wrapping each of these operations in a small data structure
-// (crazy_callback_t), which can later be passed to crazy_callback_run()
-// to execute it.
-//
-// The user must provide a function to record these callbacks during
-// library loading, by calling crazy_linker_set_callback_poster().
-//
-// Once all libraries are loaded, the callbacks can be later called either
-// in a different thread, or when it is safe to assume the system linker
-// cannot be running in parallel.
-
-// Callback handler.
-typedef void (*crazy_callback_handler_t)(void* opaque);
-
-// A small structure used to model a callback provided by the crazy linker.
-// Use crazy_callback_run() to run the callback.
-typedef struct {
-  crazy_callback_handler_t handler;
-  void* opaque;
-} crazy_callback_t;
-
-// Function to call to enable a callback into the crazy linker when delayed
-// operations are enabled (see crazy_context_set_callback_poster). A call
-// to crazy_callback_poster_t returns true if the callback was successfully
-// set up and will occur later, false if callback could not be set up (and
-// so will never occur).
-typedef bool (*crazy_callback_poster_t)(
-    crazy_callback_t* callback, void* poster_opaque);
-
-// Enable delayed operation, by passing the address of a
-// |crazy_callback_poster_t| function, that will be called during library
-// loading to let the user record callbacks for delayed operations.
-// Callers must copy the |crazy_callback_t| passed to |poster|.
-//
-// Note: If client code calls this function to supply a callback poster,
-// it must guarantee to invoke any callback requested through the poster.
-// The call will be (typically) on another thread, but may instead be
-// immediate from the poster. However, the callback must be invoked,
-// otherwise if it is a blocking callback the crazy linker will deadlock
-// waiting for it.
-//
-// |poster_opaque| is an opaque value for client code use, passed back
-// on each call to |poster|.
-// |poster| can be NULL to disable the feature.
-void crazy_context_set_callback_poster(crazy_context_t* context,
-                                       crazy_callback_poster_t poster,
-                                       void* poster_opaque);
-
-// Return the address of the function that the crazy linker can use to
-// request callbacks, and the |poster_opaque| passed back on each call
-// to |poster|. |poster| is NULL if the feature is disabled.
-void crazy_context_get_callback_poster(crazy_context_t* context,
-                                       crazy_callback_poster_t* poster,
-                                       void** poster_opaque);
-
-// Run a given |callback| in the current thread. Must only be called once
-// per callback.
-void crazy_callback_run(crazy_callback_t* callback);
-
 // Pass the platform's SDK build version to the crazy linker. The value is
 // from android.os.Build.VERSION.SDK_INT.
 void crazy_set_sdk_build_version(int sdk_build_version);
diff --git a/third_party/android_crazy_linker/src/run_tests.sh b/third_party/android_crazy_linker/src/run_tests.sh
index cb04a3ae..2271e9c 100755
--- a/third_party/android_crazy_linker/src/run_tests.sh
+++ b/third_party/android_crazy_linker/src/run_tests.sh
@@ -165,7 +165,6 @@
 crazy_linker_test_dl_wrappers_with_system_handle \
 crazy_linker_test_dl_wrappers_valid_handles \
 crazy_linker_test_load_library \
-crazy_linker_test_load_library_callbacks \
 crazy_linker_test_load_library_depends \
 crazy_linker_test_load_library_with_gnu_hash_table \
 crazy_linker_test_load_library_with_relr_relocations \
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_api.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_api.cpp
index b4d2b65d..3c85fd3 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_api.cpp
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_api.cpp
@@ -32,32 +32,17 @@
 
 struct crazy_context_t {
  public:
-  crazy_context_t()
-      : load_address(0),
-        error(),
-        search_paths(),
-        java_vm(NULL),
-        minimum_jni_version(0),
-        callback_poster(NULL),
-        callback_poster_opaque(NULL) {
-    ResetSearchPaths();
-  }
+  crazy_context_t() { ResetSearchPaths(); }
 
-  void ResetSearchPaths();
+  void ResetSearchPaths() { search_paths.ResetFromEnv("LD_LIBRARY_PATH"); }
 
-  size_t load_address;
+  size_t load_address = 0;
   Error error;
   SearchPathList search_paths;
-  void* java_vm;
-  int minimum_jni_version;
-  crazy_callback_poster_t callback_poster;
-  void* callback_poster_opaque;
+  void* java_vm = nullptr;
+  int minimum_jni_version = 0;
 };
 
-void crazy_context_t::ResetSearchPaths() {
-  search_paths.ResetFromEnv("LD_LIBRARY_PATH");
-}
-
 //
 // API functions
 //
@@ -135,64 +120,12 @@
   *minimum_jni_version = context->minimum_jni_version;
 }
 
-void crazy_context_set_callback_poster(crazy_context_t* context,
-                                       crazy_callback_poster_t poster,
-                                       void* poster_opaque) {
-  context->callback_poster = poster;
-  context->callback_poster_opaque = poster_opaque;
-}
-
-void crazy_context_get_callback_poster(crazy_context_t* context,
-                                       crazy_callback_poster_t* poster,
-                                       void** poster_opaque) {
-  *poster = context->callback_poster;
-  *poster_opaque = context->callback_poster_opaque;
-}
-
-void crazy_callback_run(crazy_callback_t* callback) {
-  (*callback->handler)(callback->opaque);
-}
-
 void crazy_context_destroy(crazy_context_t* context) { delete context; }
 
-// Scoped delayed execution, removes RDebug callbacks on scope exit.  No-op
-// if callback is NULL.
-class ScopedDelayedCallbackPoster {
- public:
-  ScopedDelayedCallbackPoster(crazy_context_t* context, RDebug* rdebug) {
-    if (context && context->callback_poster) {
-      rdebug->SetDelayedCallbackPoster(&PostFromContext, context);
-      rdebug_ = rdebug;
-    }
-  }
-
-  ~ScopedDelayedCallbackPoster() {
-    if (rdebug_)
-      rdebug_->SetDelayedCallbackPoster(nullptr, nullptr);
-  }
-
- private:
-  // Wrap callback hander and opaque into a call to a crazy_context_poster_t.
-  static bool PostFromContext(void* crazy_context,
-                              crazy_callback_handler_t handler,
-                              void* opaque) {
-    auto* context = static_cast<crazy_context_t*>(crazy_context);
-    crazy_callback_t callback;
-    callback.handler = handler;
-    callback.opaque = opaque;
-    return context->callback_poster(&callback, context->callback_poster_opaque);
-  }
-
-  // Non-null iff the context offered a callback_poster.
-  RDebug* rdebug_ = nullptr;
-};
-
 crazy_status_t crazy_library_open(crazy_library_t** library,
                                   const char* lib_name,
                                   crazy_context_t* context) {
   ScopedLockedGlobals globals;
-  ScopedDelayedCallbackPoster poster(context, globals->rdebug());
-
   LibraryView* wrap = globals->libraries()->LoadLibrary(
       lib_name, context->load_address, &context->search_paths, &context->error);
 
@@ -326,7 +259,6 @@
                                       crazy_context_t* context) {
   if (library) {
     ScopedLockedGlobals globals;
-    ScopedDelayedCallbackPoster poster(context, globals->rdebug());
     LibraryView* wrap = reinterpret_cast<LibraryView*>(library);
 
     globals->libraries()->UnloadLibrary(wrap);
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.cpp
index 73c7442..37dd145 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.cpp
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.cpp
@@ -239,99 +239,7 @@
 #endif  // !CRAZY_DISABLE_R_BRK
 }
 
-namespace {
-
-// Helper runnable class. Handler is one of the two static functions
-// AddEntryInternal() or DelEntryInternal(). Calling these invokes
-// AddEntryImpl() or DelEntryImpl() respectively on rdebug.
-class RDebugRunnable {
- public:
-  RDebugRunnable(rdebug_callback_handler_t handler,
-                 RDebug* rdebug,
-                 link_map_t* entry,
-                 bool is_blocking)
-      : handler_(handler),
-        rdebug_(rdebug),
-        entry_(entry),
-        is_blocking_(is_blocking) {}
-
-  static void Run(void* opaque);
-  static void WaitForCallback(void* opaque);
-
- private:
-  rdebug_callback_handler_t handler_;
-  RDebug* rdebug_;
-  link_map_t* entry_;
-  bool is_blocking_;
-  WaitableEvent has_run_;
-};
-
-// Callback entry point.
-void RDebugRunnable::Run(void* opaque) {
-  auto* runnable = static_cast<RDebugRunnable*>(opaque);
-
-  LOG("Callback received, runnable=%p", runnable);
-  (*runnable->handler_)(runnable->rdebug_, runnable->entry_);
-
-  if (!runnable->is_blocking_) {
-    delete runnable;
-    return;
-  }
-
-  LOG("Signalling callback, runnable=%p", runnable);
-  runnable->has_run_.Signal();
-}
-
-// For blocking callbacks, wait for the call to Run().
-void RDebugRunnable::WaitForCallback(void* opaque) {
-  auto* runnable = static_cast<RDebugRunnable*>(opaque);
-
-  if (!runnable->is_blocking_) {
-    LOG("Non-blocking, not waiting, runnable=%p", runnable);
-    return;
-  }
-
-  LOG("Waiting for signal, runnable=%p", runnable);
-  runnable->has_run_.Wait();
-
-  delete runnable;
-}
-
-}  // namespace
-
-// Helper function to schedule AddEntry() and DelEntry() calls onto another
-// thread where possible. Running them there avoids races with the system
-// linker, which expects to be able to set r_map pages readonly when it
-// is not using them and which may run simultaneously on the main thread.
-bool RDebug::PostCallback(rdebug_callback_handler_t handler,
-                          link_map_t* entry,
-                          bool is_blocking) {
-  if (!post_for_later_execution_) {
-    LOG("Deferred execution disabled");
-    return false;
-  }
-
-  RDebugRunnable* runnable =
-      new RDebugRunnable(handler, this, entry, is_blocking);
-  void* context = post_for_later_execution_context_;
-
-  if (!(*post_for_later_execution_)(context, &RDebugRunnable::Run, runnable)) {
-    LOG("Deferred execution enabled, but posting failed");
-    delete runnable;
-    return false;
-  }
-
-  LOG("Posted for later execution, runnable=%p", runnable);
-
-  if (is_blocking) {
-    RDebugRunnable::WaitForCallback(runnable);
-    LOG("Completed execution, runnable=%p", runnable);
-  }
-
-  return true;
-}
-
-void RDebug::AddEntryImpl(link_map_t* entry) {
+void RDebug::AddEntry(link_map_t* entry) {
   LOG("Adding: %s", entry->l_name);
   if (!init_)
     Init();
@@ -391,7 +299,7 @@
   CallRBrk(RT_CONSISTENT);
 }
 
-void RDebug::DelEntryImpl(link_map_t* entry) {
+void RDebug::DelEntry(link_map_t* entry) {
   if (!r_debug_)
     return;
 
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.h b/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.h
index 4e6567e..7305fa1 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.h
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.h
@@ -118,10 +118,7 @@
 // outside of its own modifications. In threaded environments where the
 // system linker and the crazy linker are operating simultaneously on
 // different threads this may be a problem; we need these pages to be
-// writable when we have to update the list. We cannot track the system
-// linker's actions, so to avoid clashing with it we may need to try and
-// move 'r_map' updates to a different thread, to serialize them with
-// other system linker activity.
+// writable when we have to update the list.
 //
 // TECHNICAL NOTE: If CRAZY_DISABLE_R_BRK is defined at compile time,
 // then the crazy linker will never try to call the r_brk() GDB Hook
@@ -154,22 +151,6 @@
   uintptr_t r_ldbase;
 };
 
-// A callback poster is a function that can be called to request a later
-// callback. Poster arguments are: an opaque pointer to the caller's
-// context, a pointer to a function with a single void* argument that will
-// handle the callback, and the opaque void* argument value to send with
-// the callback.
-typedef void (*crazy_callback_handler_t)(void* opaque);
-typedef bool (*rdebug_callback_poster_t)(void* context,
-                                         crazy_callback_handler_t,
-                                         void* opaque);
-
-// A callback handler is a static function, either AddEntryInternal() or
-// DelEntryInternal(). It calls the appropriate r_map update member
-// function, AddEntryImpl() or DelEntryImpl().
-class RDebug;
-typedef void (*rdebug_callback_handler_t)(RDebug*, link_map_t*);
-
 class RDebug {
  public:
   RDebug() = default;
@@ -178,30 +159,9 @@
   RDebug(const RDebug&) = delete;
   RDebug& operator=(const RDebug&) = delete;
 
-  // Add entries to and remove entries from the list. If post for later
-  // execution is enabled, schedule callbacks, otherwise action immediately.
-  //
-  // Callbacks may be blocking or non-blocking. On a blocking callback
-  // we wait for the other thread to call the callback before proceeding;
-  // on a non-blocking one, we proceed without waiting. Adding an entry
-  // requires a non-blocking callback, because the loop that invokes the
-  // callback is not started until after libraries are loaded. Deleting an
-  // entry requires a blocking callback, so that the objects referenced
-  // by the callback code are not destroyed before the callback is invoked.
-  void AddEntry(link_map_t* entry) {
-    RunOrDelay(&AddEntryInternal, entry, false);
-  }
-  void DelEntry(link_map_t* entry) {
-    RunOrDelay(&DelEntryInternal, entry, true);
-  }
-
-  // Assign the function used to request a callback from another thread.
-  // The context here is opaque, but is the API's crazy_context.
-  void SetDelayedCallbackPoster(rdebug_callback_poster_t poster,
-                                void* context) {
-    post_for_later_execution_ = poster;
-    post_for_later_execution_context_ = context;
-  }
+  // Add entries to and remove entries from the list.
+  void AddEntry(link_map_t* entry);
+  void DelEntry(link_map_t* entry);
 
   // Return address of current global _r_debug variable, or nullptr if not
   // available.
@@ -212,37 +172,6 @@
   // though there is no symbol for it. Returns true on success.
   bool Init();
 
-  // Support for scheduling list manipulation through callbacks.
-  // AddEntry() and DelEntry() pass the addresses of static functions to
-  // to RunOrDelay(). This requests a callback if later execution
-  // is enabled, otherwise it runs immediately on the current thread.
-  // AddEntryImpl() and DelEntryImpl() are the member functions called
-  // by the static ones to do the actual work.
-  void AddEntryImpl(link_map_t* entry);
-  void DelEntryImpl(link_map_t* entry);
-  static void AddEntryInternal(RDebug* rdebug, link_map_t* entry) {
-    rdebug->AddEntryImpl(entry);
-  }
-  static void DelEntryInternal(RDebug* rdebug, link_map_t* entry) {
-    rdebug->DelEntryImpl(entry);
-  }
-
-  // Post handler for delayed execution. Return true if delayed execution
-  // is enabled and posting succeeded. If is_blocking, waits until the
-  // callback is received before returning.
-  bool PostCallback(rdebug_callback_handler_t handler,
-                    link_map_t* entry,
-                    bool is_blocking);
-
-  // Run handler as a callback if enabled, otherwise immediately. Posts
-  // either a blocking or a non-blocking callback.
-  void RunOrDelay(rdebug_callback_handler_t handler,
-                  link_map_t* entry,
-                  bool is_blocking) {
-    if (!PostCallback(handler, entry, is_blocking))
-      (*handler)(this, entry);
-  }
-
   // Call the debugger hook function |r_debug_->r_brk|.
   // |state| is the value to write to |r_debug_->r_state|
   // before that. This is done to coordinate with the
@@ -252,8 +181,6 @@
 
   r_debug* r_debug_ = nullptr;
   bool init_ = false;
-  rdebug_callback_poster_t post_for_later_execution_ = nullptr;
-  void* post_for_later_execution_context_ = nullptr;
 };
 
 }  // namespace crazy
diff --git a/third_party/android_crazy_linker/src/tests/test_load_library_callbacks.cpp b/third_party/android_crazy_linker/src/tests/test_load_library_callbacks.cpp
deleted file mode 100644
index 2f8d84e..0000000
--- a/third_party/android_crazy_linker/src/tests/test_load_library_callbacks.cpp
+++ /dev/null
@@ -1,168 +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.
-
-// A crazy linker test to test callbacks for delayed execution.
-
-#include <stdio.h>
-#include <crazy_linker.h>
-
-#include "test_util.h"  // For Panic()
-
-#include "crazy_linker_util_threads.h"
-
-namespace {
-
-typedef void (*FunctionPtr)();
-
-// Data block passed between callback poster and callback handler.
-// It is used to hold a single crazy_callback_t instance while allowing
-// synchronization between two threads, i.e.:
-//
-//  - One thread can cann SetCallback() to set the callback.
-//
-//  - Another thread can call WaitForSetCallback() to wait for the first
-//    one to call SetCallback() and retrieve the callback value.
-//
-//  - Once SetCallback() was called, RunCallback() can be called to
-//    actually run the callback and clear the state.
-//
-class SharedState {
- public:
-  SharedState() : cond_(&mutex_) {}
-
-  // Set the callback in the shared state. This will signal WaitForSetCallback()
-  void SetCallback(crazy_callback_t callback) {
-    crazy::AutoLock m(&mutex_);
-    callback_ = callback;
-    cond_.Signal();
-  }
-
-  // Returns true iff a callback is stored in this state, e.g. after
-  // calling SetCallback().
-  bool HasCallback() const {
-    crazy::AutoLock m(&mutex_);
-    return callback_.handler != nullptr;
-  }
-
-  // Wait until SetCallback() is called from another thread.
-  // Return the corresponding value and return the callback, clearing
-  // the shared state.
-  void WaitForCallback() {
-    // Wait for the library close to call PostCallback() before returning.
-    mutex_.Lock();
-    while (!callback_.handler) {
-      cond_.Wait();
-    }
-    mutex_.Unlock();
-  }
-
-  // Run the callback. This will panic if SetCallback() was not called
-  // previously.
-  void RunCallback() {
-    if (!callback_.handler) {
-      Panic("No callback set in shared state!\n");
-    }
-    // Run the callback, then clear it.
-    crazy_callback_run(&callback_);
-    callback_.handler = nullptr;
-    callback_.opaque = nullptr;
-  }
-
-  crazy_callback_t callback_ = {};
-  mutable crazy::Mutex mutex_;
-  crazy::Condition cond_;
-};
-
-// This function is called from the crazy linker whenever a new pending
-// operation must be run on the UI thread. |callback| will have to be
-// run later from another thread in this sample program, by calling
-// crazy_callback_run().
-bool PostCallback(crazy_callback_t* callback, void* poster_opaque) {
-  printf("Post callback, poster_opaque %p, handler %p, opaque %p\n",
-         poster_opaque, callback->handler, callback->opaque);
-  reinterpret_cast<SharedState*>(poster_opaque)->SetCallback(*callback);
-  return true;
-}
-
-// A simple thread that will close a crazy_library_t instance in its
-// main body then exit immediately. Note that closing the library will
-// force the linker to wait for the completion of any callbacks that
-// were sent through PostCallback().
-class CloserThread : public crazy::ThreadBase {
- public:
-  CloserThread(crazy_library_t* library, crazy_context_t* context)
-      : library_(library), context_(context) {}
-
- private:
-  void Main() override { crazy_library_close_with_context(library_, context_); }
-
-  crazy_library_t* library_;
-  crazy_context_t* context_;
-};
-
-}  // namespace
-
-#define LIB_NAME "libcrazy_linker_tests_libfoo.so"
-
-int main() {
-  crazy_context_t* context = crazy_context_create();
-  crazy_library_t* library;
-
-  // DEBUG
-  crazy_context_set_load_address(context, 0x20000000);
-
-  // Set a callback poster, then verify it was set properly.
-  SharedState shared_state;
-  crazy_context_set_callback_poster(context, &PostCallback, &shared_state);
-  {
-    crazy_callback_poster_t poster;
-    void* poster_opaque;
-    crazy_context_get_callback_poster(context, &poster, &poster_opaque);
-    if (poster != &PostCallback || poster_opaque != &shared_state) {
-      Panic("Get callback poster error\n");
-    }
-  }
-
-  // Load library, this will end up calling PostCallback() to register
-  // a delayed linker operation to modify the global list of libraries.
-  if (!crazy_library_open(&library, LIB_NAME, context)) {
-    Panic("Could not open library: %s\n", crazy_context_get_error(context));
-  }
-
-  // Run the posted callback in the main thread. This should always work.
-  if (!shared_state.HasCallback()) {
-    Panic("Delayed callback was not received in main thread!\n");
-  }
-  shared_state.RunCallback();
-
-  // Find the "Foo" symbol.
-  FunctionPtr foo_func;
-  if (!crazy_library_find_symbol(
-           library, "Foo", reinterpret_cast<void**>(&foo_func))) {
-    Panic("Could not find 'Foo' in %s\n", LIB_NAME);
-  }
-
-  // Call it.
-  (*foo_func)();
-
-  // Closing the library will also call PostCallback() to register another
-  // callback, but the linker will then wait for its explicit completion
-  // before returning (this ensures any trace of the library was removed
-  // from the global list properly). To check this here, create a background
-  // thread to close the library, which will block until the callback is run
-  // below in the main thread.
-  {
-    CloserThread thread(library, context);
-    printf("background closing-thread created\n");
-    shared_state.WaitForCallback();
-    printf("callback received from background thread\n");
-    shared_state.RunCallback();
-    printf("callback ran in the main thread\n");
-    thread.Join();
-    printf("background thread completed, library is closed\n");
-  }
-
-  crazy_context_destroy(context);
-  return 0;
-}
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn
index 7a278c3..18f30a8 100644
--- a/third_party/blink/common/BUILD.gn
+++ b/third_party/blink/common/BUILD.gn
@@ -29,6 +29,7 @@
     "download/download_stats.cc",
     "experiments/memory_ablation_experiment.cc",
     "feature_policy/feature_policy.cc",
+    "feature_policy/policy_value.cc",
     "features.cc",
     "frame/frame_policy.cc",
     "frame/from_ad_state.cc",
diff --git a/third_party/blink/common/feature_policy/feature_policy.cc b/third_party/blink/common/feature_policy/feature_policy.cc
index fbd83fda..54b4ab2 100644
--- a/third_party/blink/common/feature_policy/feature_policy.cc
+++ b/third_party/blink/common/feature_policy/feature_policy.cc
@@ -14,13 +14,16 @@
 
 // Extracts an Allowlist from a ParsedFeaturePolicyDeclaration.
 std::unique_ptr<FeaturePolicy::Allowlist> AllowlistFromDeclaration(
-    const ParsedFeaturePolicyDeclaration& parsed_declaration) {
+    const ParsedFeaturePolicyDeclaration& parsed_declaration,
+    const FeaturePolicy::FeatureList& feature_list) {
+  mojom::PolicyValueType type =
+      feature_list.at(parsed_declaration.feature).second;
   std::unique_ptr<FeaturePolicy::Allowlist> result =
-      base::WrapUnique(new FeaturePolicy::Allowlist());
-  if (parsed_declaration.matches_all_origins)
-    result->AddAll();
-  for (const auto& origin : parsed_declaration.origins)
-    result->Add(origin);
+      base::WrapUnique(new FeaturePolicy::Allowlist(type));
+  result->SetFallbackValue(parsed_declaration.fallback_value);
+  result->SetOpaqueValue(parsed_declaration.opaque_value);
+  for (const auto& value : parsed_declaration.values)
+    result->Add(value.first, value.second);
 
   return result;
 }
@@ -28,17 +31,24 @@
 }  // namespace
 
 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration()
-    : matches_all_origins(false), matches_opaque_src(false) {}
+    : fallback_value(false), opaque_value(false) {}
 
 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration(
     mojom::FeaturePolicyFeature feature,
-    bool matches_all_origins,
-    bool matches_opaque_src,
-    std::vector<url::Origin> origins)
+    mojom::PolicyValueType type)
     : feature(feature),
-      matches_all_origins(matches_all_origins),
-      matches_opaque_src(matches_opaque_src),
-      origins(std::move(origins)) {}
+      fallback_value(PolicyValue::CreateMinPolicyValue(type)),
+      opaque_value(PolicyValue::CreateMinPolicyValue(type)) {}
+
+ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration(
+    mojom::FeaturePolicyFeature feature,
+    const std::map<url::Origin, PolicyValue> values,
+    const PolicyValue& fallback_value,
+    const PolicyValue& opaque_value)
+    : feature(feature),
+      values(std::move(values)),
+      fallback_value(std::move(fallback_value)),
+      opaque_value(std::move(opaque_value)) {}
 
 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration(
     const ParsedFeaturePolicyDeclaration& rhs) = default;
@@ -52,48 +62,63 @@
                 const ParsedFeaturePolicyDeclaration& rhs) {
   if (lhs.feature != rhs.feature)
     return false;
-  if (lhs.matches_all_origins != rhs.matches_all_origins)
+  if (!(lhs.fallback_value == rhs.fallback_value))
     return false;
-  return lhs.matches_all_origins || (lhs.origins == rhs.origins);
+  if (!(lhs.opaque_value == rhs.opaque_value))
+    return false;
+  return lhs.values == rhs.values;
 }
 
-FeaturePolicy::Allowlist::Allowlist() : matches_all_origins_(false) {}
+FeaturePolicy::Allowlist::Allowlist(mojom::PolicyValueType type)
+    : fallback_value_(PolicyValue::CreateMinPolicyValue(type)),
+      opaque_value_(PolicyValue::CreateMinPolicyValue(type)) {}
 
 FeaturePolicy::Allowlist::Allowlist(const Allowlist& rhs) = default;
 
 FeaturePolicy::Allowlist::~Allowlist() = default;
 
-void FeaturePolicy::Allowlist::Add(const url::Origin& origin) {
-  origins_.insert(origin);
+void FeaturePolicy::Allowlist::Add(const url::Origin& origin,
+                                   const PolicyValue& value) {
+  values_[origin] = value;
 }
 
-void FeaturePolicy::Allowlist::AddAll() {
-  matches_all_origins_ = true;
-}
-
-bool FeaturePolicy::Allowlist::Contains(const url::Origin& origin) const {
+PolicyValue FeaturePolicy::Allowlist::GetValueForOrigin(
+    const url::Origin& origin) const {
   // This does not handle the case where origin is an opaque origin, which is
   // also supposed to exist in the allowlist. (The identical opaque origins
   // should match in that case)
   // TODO(iclelland): Fix that, possibly by having another flag for
   // 'matches_self', which will explicitly match the policy's origin.
   // https://crbug.com/690520
-  if (matches_all_origins_) {
-    DCHECK(origins_.empty());
-    return true;
-  }
-
+  // |fallback_value_| will either be min (initialized in the parser) value or
+  // set to the corresponding value for * origins.
   if (origin.opaque())
-    return false;
-  return base::ContainsKey(origins_, origin);
+    return opaque_value_;
+
+  auto value = values_.find(origin);
+  return value == values_.end() ? fallback_value_ : value->second;
 }
 
-bool FeaturePolicy::Allowlist::MatchesAll() const {
-  return matches_all_origins_;
+const PolicyValue& FeaturePolicy::Allowlist::GetFallbackValue() const {
+  return fallback_value_;
 }
 
-const base::flat_set<url::Origin>& FeaturePolicy::Allowlist::Origins() const {
-  return origins_;
+void FeaturePolicy::Allowlist::SetFallbackValue(
+    const PolicyValue& fallback_value) {
+  fallback_value_ = fallback_value;
+}
+
+const PolicyValue& FeaturePolicy::Allowlist::GetOpaqueValue() const {
+  return opaque_value_;
+}
+
+void FeaturePolicy::Allowlist::SetOpaqueValue(const PolicyValue& opaque_value) {
+  opaque_value_ = opaque_value;
+}
+
+const base::flat_map<url::Origin, PolicyValue>&
+FeaturePolicy::Allowlist::Values() const {
+  return values_;
 }
 
 // static
@@ -107,50 +132,83 @@
 
 bool FeaturePolicy::IsFeatureEnabled(
     mojom::FeaturePolicyFeature feature) const {
-  return IsFeatureEnabledForOrigin(feature, origin_);
+  mojom::PolicyValueType feature_type = feature_list_.at(feature).second;
+  return IsFeatureEnabledForOrigin(
+      feature, origin_, PolicyValue::CreateMaxPolicyValue(feature_type));
+}
+
+bool FeaturePolicy::IsFeatureEnabled(mojom::FeaturePolicyFeature feature,
+                                     const PolicyValue& threshold_value) const {
+  return IsFeatureEnabledForOrigin(feature, origin_, threshold_value);
 }
 
 bool FeaturePolicy::IsFeatureEnabledForOrigin(
     mojom::FeaturePolicyFeature feature,
     const url::Origin& origin) const {
+  mojom::PolicyValueType feature_type = feature_list_.at(feature).second;
+  return GetFeatureValueForOrigin(feature, origin) >=
+         PolicyValue::CreateMaxPolicyValue(feature_type);
+}
+
+bool FeaturePolicy::IsFeatureEnabledForOrigin(
+    mojom::FeaturePolicyFeature feature,
+    const url::Origin& origin,
+    const PolicyValue& threshold_value) const {
+  return GetFeatureValueForOrigin(feature, origin) >= threshold_value;
+}
+
+PolicyValue FeaturePolicy::GetFeatureValueForOrigin(
+    mojom::FeaturePolicyFeature feature,
+    const url::Origin& origin) const {
   DCHECK(base::ContainsKey(feature_list_, feature));
   DCHECK(base::ContainsKey(inherited_policies_, feature));
-  if (!inherited_policies_.at(feature))
-    return false;
+  auto inherited_value = inherited_policies_.at(feature);
   auto allowlist = allowlists_.find(feature);
-  if (allowlist != allowlists_.end())
-    return allowlist->second->Contains(origin);
+  if (allowlist != allowlists_.end()) {
+    auto specified_value = allowlist->second->GetValueForOrigin(origin);
+    return PolicyValue::Combine(inherited_value, specified_value);
+  }
 
-  const FeaturePolicy::FeatureDefault default_policy =
+  // If no "allowlist" is specified, return default feature value.
+  // Note that combining value "v" with min value "min_v" is "min_v" and
+  // comining "v" with max value "max_v" is "v".
+  const FeaturePolicy::FeatureDefaultValue default_policy =
       feature_list_.at(feature);
-  if (default_policy == FeaturePolicy::FeatureDefault::EnableForAll)
-    return true;
-  if (default_policy == FeaturePolicy::FeatureDefault::EnableForSelf)
-    return origin_.IsSameOriginWith(origin);
-  return false;
+  if (default_policy.first == FeaturePolicy::FeatureDefault::DisableForAll ||
+      (default_policy.first == FeaturePolicy::FeatureDefault::EnableForSelf &&
+       !origin_.IsSameOriginWith(origin)))
+    return PolicyValue::CreateMinPolicyValue(default_policy.second);
+  return inherited_value;
 }
 
 const FeaturePolicy::Allowlist FeaturePolicy::GetAllowlistForFeature(
     mojom::FeaturePolicyFeature feature) const {
   DCHECK(base::ContainsKey(feature_list_, feature));
   DCHECK(base::ContainsKey(inherited_policies_, feature));
-  // Disabled through inheritance.
-  if (!inherited_policies_.at(feature))
-    return FeaturePolicy::Allowlist();
+  mojom::PolicyValueType type = feature_list_.at(feature).second;
+  // Return an empty allowlist when disabled through inheritance.
+  if (inherited_policies_.at(feature) <=
+      PolicyValue::CreateMinPolicyValue(type))
+    return FeaturePolicy::Allowlist(type);
 
   // Return defined policy if exists; otherwise return default policy.
   auto allowlist = allowlists_.find(feature);
   if (allowlist != allowlists_.end())
     return FeaturePolicy::Allowlist(*(allowlist->second));
 
-  const FeaturePolicy::FeatureDefault default_policy =
+  const FeaturePolicy::FeatureDefaultValue default_policy =
       feature_list_.at(feature);
-  FeaturePolicy::Allowlist default_allowlist;
+  FeaturePolicy::Allowlist default_allowlist(type);
 
-  if (default_policy == FeaturePolicy::FeatureDefault::EnableForAll)
-    default_allowlist.AddAll();
-  else if (default_policy == FeaturePolicy::FeatureDefault::EnableForSelf)
-    default_allowlist.Add(origin_);
+  if (default_policy.first == FeaturePolicy::FeatureDefault::EnableForAll) {
+    default_allowlist.SetFallbackValue(
+        PolicyValue::CreateMaxPolicyValue(default_policy.second));
+  } else if (default_policy.first ==
+             FeaturePolicy::FeatureDefault::EnableForSelf) {
+    default_allowlist.Add(
+        origin_, PolicyValue::CreateMaxPolicyValue(default_policy.second));
+  }
+
   return default_allowlist;
 }
 
@@ -160,7 +218,8 @@
        parsed_header) {
     mojom::FeaturePolicyFeature feature = parsed_declaration.feature;
     DCHECK(feature != mojom::FeaturePolicyFeature::kNotFound);
-    allowlists_[feature] = AllowlistFromDeclaration(parsed_declaration);
+    allowlists_[feature] =
+        AllowlistFromDeclaration(parsed_declaration, feature_list_);
   }
 }
 
@@ -194,11 +253,13 @@
   // https://wicg.github.io/feature-policy/#define-inherited-policy-in-container
   // returns true if |feature| is enabled in |parent_policy| for |origin|.
   for (const auto& feature : features) {
-    if (!parent_policy ||
-        parent_policy->IsFeatureEnabledForOrigin(feature.first, origin)) {
-      new_policy->inherited_policies_[feature.first] = true;
+    if (!parent_policy) {
+      // If no parent policy, set inherited policy to max value.
+      new_policy->inherited_policies_[feature.first] =
+          PolicyValue::CreateMaxPolicyValue(feature.second.second);
     } else {
-      new_policy->inherited_policies_[feature.first] = false;
+      new_policy->inherited_policies_[feature.first] =
+          parent_policy->GetFeatureValueForOrigin(feature.first, origin);
     }
   }
   if (!container_policy.empty())
@@ -223,104 +284,157 @@
     mojom::FeaturePolicyFeature feature = parsed_declaration.feature;
     // Do not allow setting a container policy for a feature which is not in the
     // feature list.
-    auto search = inherited_policies_.find(feature);
-    if (search == inherited_policies_.end())
+    auto inherited_policy = inherited_policies_.find(feature);
+    if (inherited_policy == inherited_policies_.end())
       continue;
-    bool& inherited_policy = search->second;
+    PolicyValue& inherited_value = inherited_policy->second;
     // If enabled by |parent_policy| for either |origin| or |parent_policy|'s
     // origin, then enable in the child iff the declared container policy
     // matches |origin|.
-    if (inherited_policy || parent_policy->IsFeatureEnabled(feature)) {
-      inherited_policy =
-          ((parsed_declaration.matches_opaque_src && origin_.opaque()) ||
-           AllowlistFromDeclaration(parsed_declaration)->Contains(origin_));
-    }
+    auto parent_value = parent_policy->GetFeatureValueForOrigin(
+        feature, parent_policy->origin_);
+    inherited_value =
+        inherited_value > parent_value ? inherited_value : parent_value;
+
+    inherited_value.Combine(
+        AllowlistFromDeclaration(parsed_declaration, feature_list_)
+            ->GetValueForOrigin(origin_));
   }
 }
 
+const FeaturePolicy::FeatureList& FeaturePolicy::GetFeatureList() const {
+  return feature_list_;
+}
+
 // static
 // See third_party/blink/public/common/feature_policy/feature_policy.h for
 // status of each feature (in spec, implemented, etc).
+// The second field of FeatureDefaultValue is the type of PolicyValue that is
+// asspcoated with the feature.
+// TODO(loonybear): replace boolean type value to the actual value type.
 const FeaturePolicy::FeatureList& FeaturePolicy::GetDefaultFeatureList() {
   static base::NoDestructor<FeatureList> default_feature_list(
       {{mojom::FeaturePolicyFeature::kAccelerometer,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kAccessibilityEvents,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kAmbientLightSensor,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kAutoplay,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kCamera,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kDocumentDomain,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kDocumentWrite,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kEncryptedMedia,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kFontDisplay,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kFormSubmission,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kFullscreen,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kGeolocation,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kGyroscope,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kUnoptimizedImages,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kLayoutAnimations,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kLazyLoad,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kLegacyImageFormats,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kMagnetometer,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kOversizedImages,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kMicrophone,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kMidiFeature,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kModals,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kOrientationLock,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kPayment,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kPictureInPicture,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kPointerLock,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kPopups,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kPresentation,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kScript,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kSerial,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kSpeaker,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kSyncScript,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kSyncXHR,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kTopNavigation,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kUnsizedMedia,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kUsb,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kVerticalScroll,
-        FeaturePolicy::FeatureDefault::EnableForAll},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kWakeLock,
-        FeaturePolicy::FeatureDefault::EnableForSelf},
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
        {mojom::FeaturePolicyFeature::kWebVr,
-        FeaturePolicy::FeatureDefault::EnableForSelf}});
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
+       // kFrobulate is a test only feature.
+       {mojom::FeaturePolicyFeature::kFrobulate,
+        FeatureDefaultValue(FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)}});
   return *default_feature_list;
 }
 
diff --git a/third_party/blink/common/feature_policy/feature_policy.typemap b/third_party/blink/common/feature_policy/feature_policy.typemap
index 433617d..a04133db 100644
--- a/third_party/blink/common/feature_policy/feature_policy.typemap
+++ b/third_party/blink/common/feature_policy/feature_policy.typemap
@@ -5,6 +5,7 @@
 mojom = "//third_party/blink/public/mojom/feature_policy/feature_policy.mojom"
 public_headers = [
   "//third_party/blink/public/common/feature_policy/feature_policy.h",
+  "//third_party/blink/public/common/feature_policy/policy_value.h",
   "//third_party/blink/public/common/frame/sandbox_flags.h",
 ]
 traits_headers = [
diff --git a/third_party/blink/common/feature_policy/feature_policy_mojom_traits.cc b/third_party/blink/common/feature_policy/feature_policy_mojom_traits.cc
index 468be4c..36548ec 100644
--- a/third_party/blink/common/feature_policy/feature_policy_mojom_traits.cc
+++ b/third_party/blink/common/feature_policy/feature_policy_mojom_traits.cc
@@ -12,9 +12,28 @@
                   blink::ParsedFeaturePolicyDeclaration>::
     Read(blink::mojom::ParsedFeaturePolicyDeclarationDataView in,
          blink::ParsedFeaturePolicyDeclaration* out) {
-  out->matches_all_origins = in.matches_all_origins();
+  return in.ReadFeature(&out->feature) &&
+         in.ReadFallbackValue(&out->fallback_value) &&
+         in.ReadOpaqueValue(&out->opaque_value) && in.ReadValues(&out->values);
+}
 
-  return in.ReadOrigins(&out->origins) && in.ReadFeature(&out->feature);
+bool UnionTraits<blink::mojom::PolicyValueDataDataView, blink::PolicyValue>::
+    Read(blink::mojom::PolicyValueDataDataView in, blink::PolicyValue* out) {
+  switch (in.tag()) {
+    case blink::mojom::PolicyValueDataDataView::Tag::BOOL_VALUE:
+      out->SetBoolValue(in.bool_value());
+      return true;
+    case blink::mojom::PolicyValueDataDataView::Tag::NULL_VALUE:
+      break;
+  }
+  NOTREACHED();
+  return false;
+}
+
+bool StructTraits<blink::mojom::PolicyValueDataView, blink::PolicyValue>::Read(
+    blink::mojom::PolicyValueDataView data,
+    blink::PolicyValue* out) {
+  return data.ReadData(out);
 }
 
 }  // namespace mojo
diff --git a/third_party/blink/common/feature_policy/feature_policy_mojom_traits.h b/third_party/blink/common/feature_policy/feature_policy_mojom_traits.h
index 8f8bfb9..b59ed32 100644
--- a/third_party/blink/common/feature_policy/feature_policy_mojom_traits.h
+++ b/third_party/blink/common/feature_policy/feature_policy_mojom_traits.h
@@ -5,11 +5,14 @@
 #ifndef THIRD_PARTY_BLINK_COMMON_FEATURE_POLICY_FEATURE_POLICY_MOJOM_TRAITS_H_
 #define THIRD_PARTY_BLINK_COMMON_FEATURE_POLICY_FEATURE_POLICY_MOJOM_TRAITS_H_
 
+#include <map>
 #include <vector>
 
+#include "base/containers/flat_map.h"
 #include "mojo/public/cpp/bindings/enum_traits.h"
 #include "third_party/blink/public/common/common_export.h"
 #include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/common/feature_policy/policy_value.h"
 #include "third_party/blink/public/common/frame/sandbox_flags.h"
 #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-shared.h"
 
@@ -71,6 +74,40 @@
 };
 
 template <>
+struct BLINK_COMMON_EXPORT
+    UnionTraits<blink::mojom::PolicyValueDataDataView, blink::PolicyValue> {
+ public:
+  static blink::mojom::PolicyValueDataDataView::Tag GetTag(
+      const blink::PolicyValue& value) {
+    switch (value.Type()) {
+      case blink::mojom::PolicyValueType::kNull:
+        return blink::mojom::PolicyValueDataDataView::Tag::NULL_VALUE;
+      case blink::mojom::PolicyValueType::kBool:
+        return blink::mojom::PolicyValueDataDataView::Tag::BOOL_VALUE;
+    }
+
+    NOTREACHED();
+    return blink::mojom::PolicyValueDataDataView::Tag::NULL_VALUE;
+  }
+  static bool null_value(const blink::PolicyValue& value) { return false; }
+  static bool bool_value(const blink::PolicyValue& value) {
+    return value.BoolValue();
+  }
+  static bool Read(blink::mojom::PolicyValueDataDataView in,
+                   blink::PolicyValue* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+    StructTraits<blink::mojom::PolicyValueDataView, blink::PolicyValue> {
+  static const blink::PolicyValue& data(const blink::PolicyValue& value) {
+    return value;
+  }
+  static bool Read(blink::mojom::PolicyValueDataView data,
+                   blink::PolicyValue* out);
+};
+
+template <>
 class BLINK_COMMON_EXPORT
     StructTraits<blink::mojom::ParsedFeaturePolicyDeclarationDataView,
                  blink::ParsedFeaturePolicyDeclaration> {
@@ -79,13 +116,17 @@
       const blink::ParsedFeaturePolicyDeclaration& policy) {
     return policy.feature;
   }
-  static bool matches_all_origins(
+  static const std::map<url::Origin, blink::PolicyValue>& values(
       const blink::ParsedFeaturePolicyDeclaration& policy) {
-    return policy.matches_all_origins;
+    return policy.values;
   }
-  static const std::vector<url::Origin>& origins(
+  static const blink::PolicyValue& fallback_value(
       const blink::ParsedFeaturePolicyDeclaration& policy) {
-    return policy.origins;
+    return policy.fallback_value;
+  }
+  static const blink::PolicyValue& opaque_value(
+      const blink::ParsedFeaturePolicyDeclaration& policy) {
+    return policy.opaque_value;
   }
 
   static bool Read(blink::mojom::ParsedFeaturePolicyDeclarationDataView in,
diff --git a/third_party/blink/common/feature_policy/feature_policy_unittest.cc b/third_party/blink/common/feature_policy/feature_policy_unittest.cc
index ccbfdd9..e578620 100644
--- a/third_party/blink/common/feature_policy/feature_policy_unittest.cc
+++ b/third_party/blink/common/feature_policy/feature_policy_unittest.cc
@@ -33,12 +33,18 @@
 class FeaturePolicyTest : public testing::Test {
  protected:
   FeaturePolicyTest()
-      : feature_list_(
-            {{kDefaultOnFeature, FeaturePolicy::FeatureDefault::EnableForAll},
-             {kDefaultSelfFeature,
-              FeaturePolicy::FeatureDefault::EnableForSelf},
-             {kDefaultOffFeature,
-              FeaturePolicy::FeatureDefault::DisableForAll}}) {}
+      : feature_list_({{kDefaultOnFeature,
+                        FeaturePolicy::FeatureDefaultValue(
+                            FeaturePolicy::FeatureDefault::EnableForAll,
+                            mojom::PolicyValueType::kBool)},
+                       {kDefaultSelfFeature,
+                        FeaturePolicy::FeatureDefaultValue(
+                            FeaturePolicy::FeatureDefault::EnableForSelf,
+                            mojom::PolicyValueType::kBool)},
+                       {kDefaultOffFeature,
+                        FeaturePolicy::FeatureDefaultValue(
+                            FeaturePolicy::FeatureDefault::DisableForAll,
+                            mojom::PolicyValueType::kBool)}}) {}
 
   ~FeaturePolicyTest() override = default;
 
@@ -68,6 +74,9 @@
   url::Origin origin_b_ = url::Origin::Create(GURL("https://example.net/"));
   url::Origin origin_c_ = url::Origin::Create(GURL("https://example.org/"));
 
+  const PolicyValue min_value = PolicyValue(false);
+  const PolicyValue max_value = PolicyValue(true);
+
  private:
   // Contains the list of controlled features, so that we are guaranteed to
   // have at least one of each kind of default behaviour represented.
@@ -143,10 +152,10 @@
       CreateFromParentPolicy(nullptr, origin_a_);
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
-  policy2->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
 }
 
@@ -168,10 +177,10 @@
   // they are at a different origin.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_a_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_a_);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -203,10 +212,10 @@
   // it is embedded by frame 2, for which the feature is not enabled.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_a_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -233,10 +242,10 @@
   // enabled.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -256,8 +265,9 @@
   // Default-on feature should be disabled in top-level frame.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOnFeature, false, false,
-                              std::vector<url::Origin>()}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOnFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+         min_value}}});
   EXPECT_FALSE(policy1->IsFeatureEnabled(kDefaultOnFeature));
 }
 
@@ -273,8 +283,9 @@
   // Feature should be disabled in child frame.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOnFeature, false, false,
-                              std::vector<url::Origin>()}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOnFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_a_);
   EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOnFeature));
@@ -294,8 +305,9 @@
       CreateFromParentPolicy(nullptr, origin_a_);
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
-  policy2->SetHeaderPolicy({{{kDefaultOnFeature, false, false,
-                              std::vector<url::Origin>()}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultOnFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+         min_value}}});
   EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOnFeature));
 }
 
@@ -318,10 +330,10 @@
       CreateFromParentPolicy(nullptr, origin_a_);
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
-  policy2->SetHeaderPolicy({{{kDefaultOnFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultOnFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentPolicy(policy2.get(), origin_c_);
   EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultOnFeature));
@@ -340,8 +352,9 @@
   // Default-on feature should be disabled in cross-origin child frame.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOnFeature, false, false,
-                              std::vector<url::Origin>()}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOnFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOnFeature));
@@ -363,8 +376,9 @@
   // Feature should be enabled in top and second level; disabled in frame 3.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature, true, false,
-                              std::vector<url::Origin>()}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -390,10 +404,10 @@
   // Feature should be disabled in frame 1; enabled in frames 2, 3 and 4.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOnFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOnFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -422,10 +436,10 @@
   // Feature should be disabled in frames 1 and 4; enabled in frames 2 and 3.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -454,24 +468,25 @@
   // Feature should be disabled in frames 1, 3 and 4; enabled in frame 2 only.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOffFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOffFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
-  policy2->SetHeaderPolicy({{{kDefaultOffFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultOffFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentPolicy(policy2.get(), origin_b_);
   std::unique_ptr<FeaturePolicy> policy4 =
       CreateFromParentPolicy(policy2.get(), origin_c_);
-  policy4->SetHeaderPolicy({{{kDefaultOffFeature,
-                              false,
-                              false,
-                              {origin_c_}}}});
+  policy4->SetHeaderPolicy(
+      {{{kDefaultOffFeature,
+         std::map<url::Origin, PolicyValue>{{origin_c_, max_value}}, min_value,
+         min_value}}});
+
   EXPECT_FALSE(policy1->IsFeatureEnabled(kDefaultOffFeature));
   EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultOffFeature));
   EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultOffFeature));
@@ -494,12 +509,14 @@
   // Feature should be enabled in all frames.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature, true, false,
-                              std::vector<url::Origin>()}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
-  policy2->SetHeaderPolicy({{{kDefaultSelfFeature, true, false,
-                              std::vector<url::Origin>()}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentPolicy(policy2.get(), origin_a_);
   EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
@@ -523,14 +540,15 @@
   // Feature should be enabled at the top level; disabled in all other frames.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_a_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
-  policy2->SetHeaderPolicy({{{kDefaultSelfFeature, true, false,
-                              std::vector<url::Origin>()}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentPolicy(policy2.get(), origin_a_);
   std::unique_ptr<FeaturePolicy> policy4 =
@@ -557,16 +575,18 @@
   // Feature should be enabled in all frames.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_a_, origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value},
+                                            {origin_b_, max_value}},
+         min_value, min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
-  policy2->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_b_, origin_c_}}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value},
+                                            {origin_c_, max_value}},
+         min_value, min_value}}});
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentPolicy(policy2.get(), origin_c_);
   EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
@@ -590,10 +610,11 @@
   // Feature should be enabled in frames 1, 2, and 3, and disabled in frame 4.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOnFeature,
-                              false,
-                              false,
-                              {origin_a_, origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOnFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value},
+                                            {origin_b_, max_value}},
+         min_value, min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -623,10 +644,11 @@
   // 4.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_a_, origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value},
+                                            {origin_b_, max_value}},
+         min_value, min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -658,19 +680,21 @@
   // should be enabled in frame 1, and disabled in frames 2 and 3.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_a_, origin_b_}},
-                             {kDefaultOnFeature,
-                              false,
-                              false,
-                              {origin_a_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value},
+                                            {origin_b_, max_value}},
+         min_value, min_value},
+        {kDefaultOnFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentPolicy(policy1.get(), origin_b_);
   policy2->SetHeaderPolicy(
-      {{{kDefaultSelfFeature, true, false, std::vector<url::Origin>()},
-        {kDefaultOnFeature, true, false, std::vector<url::Origin>()}}});
+      {{{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+         min_value},
+        {kDefaultOnFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+         min_value}}});
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentPolicy(policy2.get(), origin_c_);
   EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
@@ -690,10 +714,11 @@
   // and disabled for origin C.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOffFeature,
-                              false,
-                              false,
-                              {origin_a_, origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOffFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value},
+                                            {origin_b_, max_value}},
+         min_value, min_value}}});
   EXPECT_TRUE(
       policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
   EXPECT_TRUE(
@@ -723,9 +748,8 @@
       CreateFromParentPolicy(nullptr, origin_a_);
   ParsedFeaturePolicy frame_policy = {
       {{kDefaultSelfFeature,
-        false,
-        false,
-        {origin_b_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy, origin_b_);
   EXPECT_TRUE(
@@ -760,8 +784,8 @@
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
   ParsedFeaturePolicy frame_policy = {
-      {{kDefaultSelfFeature, true, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy, origin_b_);
   EXPECT_TRUE(
@@ -808,16 +832,14 @@
       CreateFromParentPolicy(nullptr, origin_a_);
   ParsedFeaturePolicy frame_policy1 = {
       {{kDefaultSelfFeature,
-        false,
-        false,
-        {origin_b_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_b_);
   ParsedFeaturePolicy frame_policy2 = {
       {{kDefaultSelfFeature,
-        false,
-        false,
-        {origin_c_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_c_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentWithFramePolicy(policy2.get(), frame_policy2, origin_c_);
   std::unique_ptr<FeaturePolicy> policy4 =
@@ -858,13 +880,13 @@
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
   ParsedFeaturePolicy frame_policy1 = {
-      {{kDefaultOnFeature, false, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultOnFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_a_);
   ParsedFeaturePolicy frame_policy2 = {
-      {{kDefaultOnFeature, false, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultOnFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
   EXPECT_TRUE(policy1->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_a_));
@@ -905,22 +927,20 @@
   // child frames because they did not declare their own policy to enable it.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOffFeature,
-                              false,
-                              false,
-                              {origin_a_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOffFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+         min_value}}});
   ParsedFeaturePolicy frame_policy1 = {
       {{kDefaultOffFeature,
-        false,
-        false,
-        {origin_a_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_a_);
   ParsedFeaturePolicy frame_policy2 = {
       {{kDefaultOffFeature,
-        false,
-        false,
-        {origin_b_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
   EXPECT_TRUE(
@@ -965,32 +985,30 @@
   // they declare their own policy to enable it.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultOffFeature,
-                              false,
-                              false,
-                              {origin_a_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultOffFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+         min_value}}});
   ParsedFeaturePolicy frame_policy1 = {
       {{kDefaultOffFeature,
-        false,
-        false,
-        {origin_a_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_a_);
-  policy2->SetHeaderPolicy({{{kDefaultOffFeature,
-                              false,
-                              false,
-                              {origin_a_}}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultOffFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+         min_value}}});
   ParsedFeaturePolicy frame_policy2 = {
       {{kDefaultOffFeature,
-        false,
-        false,
-        {origin_b_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
-  policy3->SetHeaderPolicy({{{kDefaultOffFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy3->SetHeaderPolicy(
+      {{{kDefaultOffFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   EXPECT_TRUE(
       policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
   EXPECT_FALSE(
@@ -1034,24 +1052,25 @@
   // policy.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_a_, origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_a_, max_value},
+                                            {origin_b_, max_value}},
+         min_value, min_value}}});
   ParsedFeaturePolicy frame_policy1 = {
-      {{kDefaultSelfFeature, false, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_b_);
   ParsedFeaturePolicy frame_policy2 = {
-      {{kDefaultSelfFeature, false, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
-  policy3->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy3->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   EXPECT_FALSE(
       policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
   EXPECT_FALSE(
@@ -1087,16 +1106,16 @@
       CreateFromParentPolicy(nullptr, origin_a_);
   ParsedFeaturePolicy frame_policy1 = {
       {{kDefaultSelfFeature,
-        false,
-        false,
-        {origin_b_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_b_);
-  policy2->SetHeaderPolicy({{{kDefaultSelfFeature, true, false,
-                              std::vector<url::Origin>()}}});
+  policy2->SetHeaderPolicy(
+      {{{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+         min_value}}});
   ParsedFeaturePolicy frame_policy2 = {
-      {{kDefaultSelfFeature, false, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentWithFramePolicy(policy2.get(), frame_policy2, origin_c_);
   std::unique_ptr<FeaturePolicy> policy4 =
@@ -1131,18 +1150,18 @@
   // Default-self feature should be disabled in all frames.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature, false, false,
-                              std::vector<url::Origin>()}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+         min_value}}});
   ParsedFeaturePolicy frame_policy1 = {
       {{kDefaultSelfFeature,
-        false,
-        false,
-        {origin_b_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_b_);
   ParsedFeaturePolicy frame_policy2 = {
-      {{kDefaultSelfFeature, true, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_a_);
   EXPECT_FALSE(
@@ -1180,27 +1199,25 @@
   // enabled in the remaining frames.
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature,
-                              false,
-                              false,
-                              {origin_b_}}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature,
+         std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+         min_value}}});
   ParsedFeaturePolicy frame_policy1 = {
       {{kDefaultSelfFeature,
-        false,
-        false,
-        {origin_a_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_a_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_b_);
   ParsedFeaturePolicy frame_policy2 = {
       {{kDefaultSelfFeature,
-        false,
-        false,
-        {origin_b_}}}};
+        std::map<url::Origin, PolicyValue>{{origin_b_, max_value}}, min_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy3 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
   ParsedFeaturePolicy frame_policy3 = {
-      {{kDefaultSelfFeature, true, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy4 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy3, origin_b_);
   EXPECT_FALSE(
@@ -1266,8 +1283,8 @@
       CreateFromParentPolicy(nullptr, origin_a_);
   url::Origin sandboxed_origin = url::Origin();
   ParsedFeaturePolicy frame_policy = {
-      {{kDefaultSelfFeature, true, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+        max_value}}};
   std::unique_ptr<FeaturePolicy> policy2 = CreateFromParentWithFramePolicy(
       policy1.get(), frame_policy, sandboxed_origin);
   EXPECT_TRUE(policy2->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_a_));
@@ -1298,8 +1315,8 @@
       CreateFromParentPolicy(nullptr, origin_a_);
   url::Origin sandboxed_origin = url::Origin();
   ParsedFeaturePolicy frame_policy = {
-      {{kDefaultSelfFeature, false, true,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+        max_value}}};
   std::unique_ptr<FeaturePolicy> policy2 = CreateFromParentWithFramePolicy(
       policy1.get(), frame_policy, sandboxed_origin);
   EXPECT_TRUE(policy2->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_a_));
@@ -1327,12 +1344,13 @@
   // However, it will not pass that on to any other origin
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
-  policy1->SetHeaderPolicy({{{kDefaultSelfFeature, true, false,
-                              std::vector<url::Origin>()}}});
+  policy1->SetHeaderPolicy(
+      {{{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+         min_value}}});
   url::Origin sandboxed_origin = url::Origin();
   ParsedFeaturePolicy frame_policy = {
-      {{kDefaultSelfFeature, false, true,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+        max_value}}};
   std::unique_ptr<FeaturePolicy> policy2 = CreateFromParentWithFramePolicy(
       policy1.get(), frame_policy, sandboxed_origin);
   EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
@@ -1365,8 +1383,8 @@
   url::Origin sandboxed_origin_1 = url::Origin();
   url::Origin sandboxed_origin_2 = url::Origin();
   ParsedFeaturePolicy frame_policy = {
-      {{kDefaultSelfFeature, true, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+        min_value}}};
   std::unique_ptr<FeaturePolicy> policy2 = CreateFromParentWithFramePolicy(
       policy1.get(), frame_policy, sandboxed_origin_1);
   std::unique_ptr<FeaturePolicy> policy3 =
@@ -1410,13 +1428,13 @@
   url::Origin sandboxed_origin_1 = origin_a_.DeriveNewOpaqueOrigin();
   url::Origin sandboxed_origin_2 = sandboxed_origin_1.DeriveNewOpaqueOrigin();
   ParsedFeaturePolicy frame_policy_1 = {
-      {{kDefaultSelfFeature, true, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+        max_value}}};
   std::unique_ptr<FeaturePolicy> policy2 = CreateFromParentWithFramePolicy(
       policy1.get(), frame_policy_1, sandboxed_origin_1);
   ParsedFeaturePolicy frame_policy_2 = {
-      {{kDefaultSelfFeature, true, false,
-        std::vector<url::Origin>()}}};
+      {{kDefaultSelfFeature, std::map<url::Origin, PolicyValue>{}, max_value,
+        max_value}}};
   std::unique_ptr<FeaturePolicy> policy3 = CreateFromParentWithFramePolicy(
       policy2.get(), frame_policy_2, sandboxed_origin_2);
   EXPECT_TRUE(policy3->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_a_));
@@ -1447,9 +1465,10 @@
   std::unique_ptr<FeaturePolicy> policy1 =
       CreateFromParentPolicy(nullptr, origin_a_);
   ParsedFeaturePolicy frame_policy = {
-      {{mojom::FeaturePolicyFeature::kNotFound, false, true,
-        std::vector<url::Origin>()},
-       {kUnavailableFeature, false, true, std::vector<url::Origin>()}}};
+      {{mojom::FeaturePolicyFeature::kNotFound,
+        std::map<url::Origin, PolicyValue>{}, min_value, max_value},
+       {kUnavailableFeature, std::map<url::Origin, PolicyValue>{}, min_value,
+        max_value}}};
   std::unique_ptr<FeaturePolicy> policy2 =
       CreateFromParentWithFramePolicy(policy1.get(), frame_policy, origin_b_);
   EXPECT_FALSE(PolicyContainsInheritedValue(
diff --git a/third_party/blink/common/feature_policy/policy_value.cc b/third_party/blink/common/feature_policy/policy_value.cc
new file mode 100644
index 0000000..92b346c5
--- /dev/null
+++ b/third_party/blink/common/feature_policy/policy_value.cc
@@ -0,0 +1,141 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+
+namespace blink {
+
+PolicyValue::PolicyValue() : type_(mojom::PolicyValueType::kNull) {}
+
+PolicyValue::~PolicyValue() = default;
+
+PolicyValue::PolicyValue(mojom::PolicyValueType type) : type_(type) {
+  DCHECK_EQ(type, mojom::PolicyValueType::kNull);
+}
+
+PolicyValue::PolicyValue(bool bool_value)
+    : type_(mojom::PolicyValueType::kBool), bool_value_(bool_value) {}
+
+PolicyValue PolicyValue::CreateMaxPolicyValue(mojom::PolicyValueType type) {
+  PolicyValue value;
+  value.SetType(type);
+  value.SetToMax();
+  return value;
+}
+
+PolicyValue PolicyValue::CreateMinPolicyValue(mojom::PolicyValueType type) {
+  PolicyValue value;
+  value.SetType(type);
+  value.SetToMin();
+  return value;
+}
+
+bool PolicyValue::BoolValue() const {
+  DCHECK_EQ(type_, mojom::PolicyValueType::kBool);
+  return bool_value_;
+}
+
+void PolicyValue::SetBoolValue(bool bool_value) {
+  type_ = mojom::PolicyValueType::kBool;
+  bool_value_ = bool_value;
+}
+
+PolicyValue& PolicyValue::operator=(const PolicyValue& rhs) {
+  if (this != &rhs) {
+    type_ = rhs.type_;
+    bool_value_ = rhs.bool_value_;
+  }
+  return *this;
+}
+
+PolicyValue PolicyValue::Combine(const PolicyValue& lhs,
+                                 const PolicyValue& rhs) {
+  DCHECK_EQ(lhs.Type(), rhs.Type());
+  PolicyValue final_value;
+  final_value.SetType(lhs.Type());
+  switch (lhs.Type()) {
+    case mojom::PolicyValueType::kBool:
+      final_value.SetBoolValue(lhs.BoolValue() && rhs.BoolValue());
+      break;
+    default:
+      NOTREACHED();
+  }
+  return final_value;
+}
+
+void PolicyValue::Combine(const PolicyValue& rhs) {
+  DCHECK_EQ(type_, rhs.Type());
+  switch (type_) {
+    case mojom::PolicyValueType::kBool:
+      SetBoolValue(bool_value_ && rhs.BoolValue());
+      break;
+    default:
+      NOTREACHED();
+  }
+}
+
+bool operator==(const PolicyValue& lhs, const PolicyValue& rhs) {
+  if (lhs.Type() != rhs.Type())
+    return false;
+  switch (lhs.Type()) {
+    case mojom::PolicyValueType::kBool:
+      return lhs.BoolValue() == rhs.BoolValue();
+    case mojom::PolicyValueType::kNull:
+      return true;
+  }
+  NOTREACHED();
+  return false;
+}
+
+bool operator!=(const PolicyValue& lhs, const PolicyValue& rhs) {
+  return !(lhs == rhs);
+}
+
+bool operator<(const PolicyValue& lhs, const PolicyValue& rhs) {
+  DCHECK_EQ(lhs.Type(), rhs.Type());
+  switch (lhs.Type()) {
+    case mojom::PolicyValueType::kBool:
+      return rhs.BoolValue();
+    case mojom::PolicyValueType::kNull:
+      NOTREACHED();
+      break;
+  }
+  return false;
+}
+
+bool operator<=(const PolicyValue& lhs, const PolicyValue& rhs) {
+  return lhs < rhs || lhs == rhs;
+}
+
+bool operator>(const PolicyValue& lhs, const PolicyValue& rhs) {
+  return rhs < lhs;
+}
+
+bool operator>=(const PolicyValue& lhs, const PolicyValue& rhs) {
+  return rhs < lhs || rhs == lhs;
+}
+
+void PolicyValue::SetToMax() {
+  switch (type_) {
+    case mojom::PolicyValueType::kBool:
+      bool_value_ = true;
+      break;
+    default:
+      break;
+  }
+  return;
+}
+
+void PolicyValue::SetToMin() {
+  switch (type_) {
+    case mojom::PolicyValueType::kBool:
+      bool_value_ = false;
+      break;
+    default:
+      NOTREACHED();
+  }
+  return;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn
index 090989b1..74013706 100644
--- a/third_party/blink/public/common/BUILD.gn
+++ b/third_party/blink/public/common/BUILD.gn
@@ -44,6 +44,7 @@
     "download/download_stats.h",
     "experiments/memory_ablation_experiment.h",
     "feature_policy/feature_policy.h",
+    "feature_policy/policy_value.h",
     "features.h",
     "fetch/fetch_api_request_headers_map.h",
     "fetch/fetch_api_request_headers_mojom_traits.h",
diff --git a/third_party/blink/public/common/feature_policy/feature_policy.h b/third_party/blink/public/common/feature_policy/feature_policy.h
index fbaf0e1..ae47430 100644
--- a/third_party/blink/public/common/feature_policy/feature_policy.h
+++ b/third_party/blink/public/common/feature_policy/feature_policy.h
@@ -7,12 +7,15 @@
 
 #include <map>
 #include <memory>
+#include <utility>
 #include <vector>
 
+#include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "third_party/blink/public/common/common_export.h"
+#include "third_party/blink/public/common/feature_policy/policy_value.h"
 #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h"
 #include "url/origin.h"
 
@@ -83,32 +86,42 @@
 // determined by the feature's default policy. (Again, see the comments in
 // FeaturePolicy::DefaultPolicy for details)
 
+// ListValue (PolicyValue)
+// ----------------------
+// PolicyValue is a union of types (int / double / set<int> / bool ) that can be
+// used to specify the parameter of a policy.
+
 // This struct holds feature policy allowlist data that needs to be replicated
 // between a RenderFrame and any of its associated RenderFrameProxies. A list of
 // these form a ParsedFeaturePolicy.
 // NOTE: These types are used for replication frame state between processes.
-// TODO(lunalu): Remove unnecessary types used for transferring over IPC.
+
 struct BLINK_COMMON_EXPORT ParsedFeaturePolicyDeclaration {
   ParsedFeaturePolicyDeclaration();
   ParsedFeaturePolicyDeclaration(mojom::FeaturePolicyFeature feature,
-                                 bool matches_all_origins,
-                                 bool matches_opaque_src,
-                                 std::vector<url::Origin> origins);
+                                 mojom::PolicyValueType type);
+  ParsedFeaturePolicyDeclaration(
+      mojom::FeaturePolicyFeature feature,
+      const std::map<url::Origin, PolicyValue> values,
+      const PolicyValue& fallback_value,
+      const PolicyValue& opaque_value);
   ParsedFeaturePolicyDeclaration(const ParsedFeaturePolicyDeclaration& rhs);
   ParsedFeaturePolicyDeclaration& operator=(
       const ParsedFeaturePolicyDeclaration& rhs);
   ~ParsedFeaturePolicyDeclaration();
 
   mojom::FeaturePolicyFeature feature;
-  bool matches_all_origins;
   // This flag is set true for a declared policy on an <iframe sandbox>
   // container, for a feature which is supposed to be allowed in the sandboxed
   // document. Usually, the 'src' keyword in a declaration will cause the origin
   // of the iframe to be present in |origins|, but for sandboxed iframes, this
   // flag is set instead.
-  bool matches_opaque_src;
-  // An alphabetically sorted list of all the origins allowed.
-  std::vector<url::Origin> origins;
+
+  // This map records all the allowed origins and their corresponding values.
+  std::map<url::Origin, PolicyValue> values;
+  // Fallback value is used when feature is enabled for all or disabled for all.
+  PolicyValue fallback_value;
+  PolicyValue opaque_value;
 };
 
 using ParsedFeaturePolicy = std::vector<ParsedFeaturePolicyDeclaration>;
@@ -124,28 +137,40 @@
   // will always return true.
   class BLINK_COMMON_EXPORT Allowlist final {
    public:
-    Allowlist();
+    Allowlist(mojom::PolicyValueType type);
     Allowlist(const Allowlist& rhs);
     ~Allowlist();
 
     // Adds a single origin to the allowlist.
-    void Add(const url::Origin& origin);
+    void Add(const url::Origin& origin, const PolicyValue& value);
 
-    // Adds all origins to the allowlist.
-    void AddAll();
+    // Returns the value of the given origin if specified, fallback value
+    // otherwise.
+    // fallback value should be set to maximum unless it is set to 'none'.
+    PolicyValue GetValueForOrigin(const url::Origin& origin) const;
 
-    // Returns true if the given origin has been added to the allowlist.
-    bool Contains(const url::Origin& origin) const;
+    // Returns the fallback value.
+    const PolicyValue& GetFallbackValue() const;
 
-    // Returns true if the allowlist matches all origins.
-    bool MatchesAll() const;
+    // Sets the fallback value.
+    void SetFallbackValue(const PolicyValue& fallback_value);
+
+    // Returns the opaque value.
+    const PolicyValue& GetOpaqueValue() const;
+
+    // Sets the opaque value.
+    void SetOpaqueValue(const PolicyValue& opaque_value);
 
     // Returns set of origins in the allowlist.
     const base::flat_set<url::Origin>& Origins() const;
 
+    // Returns set of <origin, value> pair in the allowlist.
+    const base::flat_map<url::Origin, PolicyValue>& Values() const;
+
    private:
-    bool matches_all_origins_;
-    base::flat_set<url::Origin> origins_;
+    base::flat_map<url::Origin, PolicyValue> values_;
+    PolicyValue fallback_value_;
+    PolicyValue opaque_value_;
   };
 
   // The FeaturePolicy::FeatureDefault enum defines the default enable state for
@@ -167,7 +192,10 @@
     EnableForAll
   };
 
-  using FeatureList = std::map<mojom::FeaturePolicyFeature, FeatureDefault>;
+  using FeatureDefaultValue =
+      std::pair<FeaturePolicy::FeatureDefault, mojom::PolicyValueType>;
+  using FeatureList =
+      std::map<mojom::FeaturePolicyFeature, FeaturePolicy::FeatureDefaultValue>;
 
   ~FeaturePolicy();
 
@@ -178,10 +206,20 @@
 
   bool IsFeatureEnabled(mojom::FeaturePolicyFeature feature) const;
 
+  bool IsFeatureEnabled(mojom::FeaturePolicyFeature feature,
+                        const PolicyValue& threshold_value) const;
+
   // Returns whether or not the given feature is enabled by this policy for a
   // specific origin.
   bool IsFeatureEnabledForOrigin(mojom::FeaturePolicyFeature feature,
                                  const url::Origin& origin) const;
+  bool IsFeatureEnabledForOrigin(mojom::FeaturePolicyFeature feature,
+                                 const url::Origin& origin,
+                                 const PolicyValue& threshold_value) const;
+
+  // Returns the value of the given feature on the given origin.
+  PolicyValue GetFeatureValueForOrigin(mojom::FeaturePolicyFeature feature,
+                                       const url::Origin& origin) const;
 
   // Returns the allowlist of a given feature by this policy.
   const Allowlist GetAllowlistForFeature(
@@ -193,6 +231,10 @@
 
   const url::Origin& GetOriginForTest() { return origin_; }
 
+  // Returns the list of features which can be controlled by Feature Policy.
+  const FeatureList& GetFeatureList() const;
+  static const FeatureList& GetDefaultFeatureList();
+
  private:
   friend class FeaturePolicyTest;
 
@@ -208,9 +250,6 @@
   void AddContainerPolicy(const ParsedFeaturePolicy& container_policy,
                           const FeaturePolicy* parent_policy);
 
-  // Returns the list of features which can be controlled by Feature Policy.
-  static const FeatureList& GetDefaultFeatureList();
-
   // The origin of the document with which this policy is associated.
   url::Origin origin_;
 
@@ -220,9 +259,7 @@
 
   // Records whether or not each feature was enabled for this frame by its
   // parent frame.
-  // TODO(iclelland): Generate, instead of this map, a set of bool flags, one
-  // for each feature, as all features are supposed to be represented here.
-  std::map<mojom::FeaturePolicyFeature, bool> inherited_policies_;
+  std::map<mojom::FeaturePolicyFeature, PolicyValue> inherited_policies_;
 
   const FeatureList& feature_list_;
 
diff --git a/third_party/blink/public/common/feature_policy/policy_value.h b/third_party/blink/public/common/feature_policy/policy_value.h
new file mode 100644
index 0000000..a51972a
--- /dev/null
+++ b/third_party/blink/public/common/feature_policy/policy_value.h
@@ -0,0 +1,73 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_POLICY_VALUE_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_POLICY_VALUE_H_
+
+#include "base/macros.h"
+#include "third_party/blink/public/common/common_export.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h"
+
+namespace blink {
+
+// ListValue (PolicyValue)
+// ----------------------
+// PolicyValue is a union of types (int / double / set<int> / bool ) that can be
+// used to specify the parameter of a policy.
+
+// TODO(loonybear): Add the following types: inc/dec int, inc/dec double, set.
+class BLINK_COMMON_EXPORT PolicyValue {
+ public:
+  PolicyValue();
+  ~PolicyValue();
+
+  explicit PolicyValue(mojom::PolicyValueType);
+
+  explicit PolicyValue(bool bool_value);
+
+  // A 'max' PolicyValue is the most permissive value for the policy.
+  static PolicyValue CreateMaxPolicyValue(mojom::PolicyValueType type);
+  // A 'min' PolicyValue is the most restrictive value for the policy.
+  static PolicyValue CreateMinPolicyValue(mojom::PolicyValueType type);
+
+  mojom::PolicyValueType Type() const { return type_; }
+  void SetType(mojom::PolicyValueType type) { type_ = type; }
+
+  // PolicyValue getters.
+  // Note the getters also DCHECKs that the type is correct.
+  bool BoolValue() const;
+
+  // PolicyValue setters.
+  void SetBoolValue(bool bool_value);
+
+  // Operater overrides
+  PolicyValue& operator=(const PolicyValue& rhs);
+  // Combine a new PolicyValue to self, by taking the stricter value of the two.
+  void Combine(const PolicyValue& value);
+  // Combine two PolicyValue_s together by taking the stricter value of the two.
+  static PolicyValue Combine(const PolicyValue& lhs, const PolicyValue& rhs);
+
+  void SetToMax();
+  void SetToMin();
+
+ private:
+  mojom::PolicyValueType type_;
+  bool bool_value_;
+};
+
+bool BLINK_COMMON_EXPORT operator==(const PolicyValue& lhs,
+                                    const PolicyValue& rhs);
+bool BLINK_COMMON_EXPORT operator!=(const PolicyValue& lhs,
+                                    const PolicyValue& rhs);
+bool BLINK_COMMON_EXPORT operator>(const PolicyValue& lhs,
+                                   const PolicyValue& rhs);
+bool BLINK_COMMON_EXPORT operator>=(const PolicyValue& lhs,
+                                    const PolicyValue& rhs);
+bool BLINK_COMMON_EXPORT operator<(const PolicyValue& lhs,
+                                   const PolicyValue& rhs);
+bool BLINK_COMMON_EXPORT operator<=(const PolicyValue& lhs,
+                                    const PolicyValue& rhs);
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_POLICY_VALUE_H_
diff --git a/third_party/blink/public/mojom/feature_policy/feature_policy.mojom b/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
index d470f266..1364aa0f 100644
--- a/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
+++ b/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
@@ -133,12 +133,33 @@
   kReport,
 };
 
+// This enum defines the types of parameters used to specify a feature policy.
+// TODO(loonybear): Add the following types: inc/dec int, inc/dec double, set.
+enum PolicyValueType {
+  kNull,
+  kBool,
+};
+
+// This union includes all the types that can be used to specify a policy's
+// parameter.
+// TODO(loonybear): Add the following types: inc/dec int, inc/dec double, set.
+union PolicyValueData {
+  bool null_value;
+  bool bool_value;
+};
+
+// Defined as a structure so that it can be typemapped with StructTraits.
+struct PolicyValue {
+  PolicyValueData data;
+};
+
 // This struct holds feature policy allowlist data that needs to be replicated
 // between a RenderFrame and any of its associated RenderFrameProxies. A list of
 // these form a ParsedFeaturePolicy.
 // NOTE: These types are used for replication frame state between processes.
 struct ParsedFeaturePolicyDeclaration {
   FeaturePolicyFeature feature;
-  bool matches_all_origins;
-  array<url.mojom.Origin> origins;
+  map<url.mojom.Origin, PolicyValue> values;
+  PolicyValue fallback_value;
+  PolicyValue opaque_value;
 };
diff --git a/third_party/blink/renderer/bindings/core/v8/script_source_code.h b/third_party/blink/renderer/bindings/core/v8/script_source_code.h
index 96042ce..8fe2bd4e 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_source_code.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_source_code.h
@@ -122,6 +122,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::ScriptSourceCode);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::ScriptSourceCode)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_SOURCE_CODE_H_
diff --git a/third_party/blink/renderer/bindings/templates/union_container.h.tmpl b/third_party/blink/renderer/bindings/templates/union_container.h.tmpl
index e264980..1c7971d1 100644
--- a/third_party/blink/renderer/bindings/templates/union_container.h.tmpl
+++ b/third_party/blink/renderer/bindings/templates/union_container.h.tmpl
@@ -82,7 +82,7 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::{{cpp_class}});
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::{{cpp_class}})
 
 #endif  // {{header_guard}}
 
diff --git a/third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.h b/third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.h
index 40ca850..e6b74feb 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.h
@@ -102,6 +102,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ArrayBufferOrArrayBufferViewOrDictionary);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ArrayBufferOrArrayBufferViewOrDictionary)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_ARRAY_BUFFER_OR_ARRAY_BUFFER_VIEW_OR_DICTIONARY_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.h b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.h
index 9849278..d2f4646 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.h
@@ -92,6 +92,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrElementSequence);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrElementSequence)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_BOOLEAN_OR_ELEMENT_SEQUENCE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.h b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.h
index e2e6a91ea..8f57680a0 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.h
@@ -97,6 +97,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrStringOrUnrestrictedDouble);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrStringOrUnrestrictedDouble)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_BOOLEAN_OR_STRING_OR_UNRESTRICTED_DOUBLE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.h b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.h
index bd0001cc..5923c5d1 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.h
@@ -92,6 +92,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrTestCallbackInterface);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrTestCallbackInterface)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_BOOLEAN_OR_TEST_CALLBACK_INTERFACE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.h b/third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.h
index f44c9e0..74cc5fb7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.h
@@ -92,6 +92,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ByteStringOrNodeList);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ByteStringOrNodeList)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_BYTE_STRING_OR_NODE_LIST_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.h b/third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.h
index db106c9..b3edd0a 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ByteStringSequenceSequenceOrByteStringByteStringRecord);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ByteStringSequenceSequenceOrByteStringByteStringRecord)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_BYTE_STRING_SEQUENCE_SEQUENCE_OR_BYTE_STRING_BYTE_STRING_RECORD_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.h b/third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.h
index 673c45c..e1d2c48 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrDoubleOrNullSequence);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrDoubleOrNullSequence)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_DOUBLE_OR_DOUBLE_OR_NULL_SEQUENCE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.h b/third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.h
index 680b470..880bce0 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrDoubleSequence);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrDoubleSequence)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_DOUBLE_OR_DOUBLE_SEQUENCE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.h b/third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.h
index 9f1cd1b..ec99865 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.h
@@ -92,6 +92,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrLongOrBooleanSequence);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrLongOrBooleanSequence)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_DOUBLE_OR_LONG_OR_BOOLEAN_SEQUENCE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_string.h b/third_party/blink/renderer/bindings/tests/results/core/double_or_string.h
index 5a5a9bf..48bef0a7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_string.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_string.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrString);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrString)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_DOUBLE_OR_STRING_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.h b/third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.h
index 487d5a7..c981373 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.h
@@ -99,6 +99,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrStringOrDoubleOrStringSequence);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrStringOrDoubleOrStringSequence)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_DOUBLE_OR_STRING_OR_DOUBLE_OR_STRING_SEQUENCE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.h b/third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.h
index 7d5ab3f400..55da95b 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.h
@@ -93,6 +93,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ElementSequenceOrByteStringDoubleOrStringRecord);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ElementSequenceOrByteStringDoubleOrStringRecord)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_ELEMENT_SEQUENCE_OR_BYTE_STRING_DOUBLE_OR_STRING_RECORD_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.h b/third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.h
index 7afcdb87..07fb5e3 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::FloatOrBoolean);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::FloatOrBoolean)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_FLOAT_OR_BOOLEAN_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.h b/third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.h
index e2fd432..49caa052 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::LongOrBoolean);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::LongOrBoolean)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_LONG_OR_BOOLEAN_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.h b/third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.h
index a40452f3..b57b943 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.h
@@ -91,6 +91,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::LongOrTestDictionary);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::LongOrTestDictionary)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_LONG_OR_TEST_DICTIONARY_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.h b/third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.h
index 4d099d7..dda41f3 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.h
@@ -92,6 +92,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::LongSequenceOrEvent);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::LongSequenceOrEvent)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_LONG_SEQUENCE_OR_EVENT_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/nested_union_type.h b/third_party/blink/renderer/bindings/tests/results/core/nested_union_type.h
index 76ecb8b..d9403628 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/nested_union_type.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/nested_union_type.h
@@ -123,6 +123,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_NESTED_UNION_TYPE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.h b/third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.h
index bd2cb51..87a0431 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.h
@@ -93,6 +93,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::NodeOrNodeList);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::NodeOrNodeList)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_NODE_OR_NODE_LIST_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.h b/third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.h
index 447522f5..90445a7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.h
@@ -102,6 +102,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrArrayBufferOrArrayBufferView);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrArrayBufferOrArrayBufferView)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_STRING_OR_ARRAY_BUFFER_OR_ARRAY_BUFFER_VIEW_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/string_or_double.h b/third_party/blink/renderer/bindings/tests/results/core/string_or_double.h
index 8166f47c..24e695c 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/string_or_double.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/string_or_double.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrDouble);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrDouble)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_STRING_OR_DOUBLE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.h b/third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.h
index 5623de0a..d53f688 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrStringSequence);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrStringSequence)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_STRING_OR_STRING_SEQUENCE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/string_treat_null_as_empty_string_or_long.h b/third_party/blink/renderer/bindings/tests/results/core/string_treat_null_as_empty_string_or_long.h
index 97bcf28..ed3b4f62 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/string_treat_null_as_empty_string_or_long.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/string_treat_null_as_empty_string_or_long.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringTreatNullAsEmptyStringOrLong);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringTreatNullAsEmptyStringOrLong)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_STRING_TREAT_NULL_AS_EMPTY_STRING_OR_LONG_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.h b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.h
index 6251605ea..645e2421 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestEnumOrDouble);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestEnumOrDouble)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_TEST_ENUM_OR_DOUBLE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.h b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.h
index 8a02891..127eb683 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestEnumOrTestEnumOrNullSequence);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestEnumOrTestEnumOrNullSequence)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_TEST_ENUM_OR_TEST_ENUM_OR_NULL_SEQUENCE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.h b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.h
index d2a9d1f..7154990 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestEnumOrTestEnumSequence);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestEnumOrTestEnumSequence)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_TEST_ENUM_OR_TEST_ENUM_SEQUENCE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.h b/third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.h
index 0fb6062f..22a8a0d4 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.h
@@ -96,6 +96,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterface2OrUint8Array);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterface2OrUint8Array)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_TEST_INTERFACE_2_OR_UINT_8_ARRAY_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.h b/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.h
index 79b5c9f..c9fee9f 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.h
@@ -92,6 +92,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterfaceOrLong);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterfaceOrLong)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_TEST_INTERFACE_OR_LONG_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.h b/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.h
index 3c7ddf2..5a5c1c2 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.h
@@ -93,6 +93,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterfaceOrTestInterfaceEmpty);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterfaceOrTestInterfaceEmpty)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_TEST_INTERFACE_OR_TEST_INTERFACE_EMPTY_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.h b/third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.h
index 192ecf2..e7924ca 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::UnrestrictedDoubleOrString);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::UnrestrictedDoubleOrString)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_UNRESTRICTED_DOUBLE_OR_STRING_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.h b/third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.h
index 1ddf479..37203322 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.h
@@ -99,6 +99,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::UnsignedLongLongOrBooleanOrTestCallbackInterface);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::UnsignedLongLongOrBooleanOrTestCallbackInterface)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_UNSIGNED_LONG_LONG_OR_BOOLEAN_OR_TEST_CALLBACK_INTERFACE_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.h b/third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.h
index 7f998a5..d28f3ef 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.h
@@ -92,6 +92,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::XMLHttpRequestOrString);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::XMLHttpRequestOrString)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_CORE_XML_HTTP_REQUEST_OR_STRING_H_
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.h b/third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.h
index be182f4..782063ed 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.h
+++ b/third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.h
@@ -90,6 +90,6 @@
 // items that can initialize with memset or have a vtable. It is safe to
 // set canInitializeWithMemset=true for a union type object in practice.
 // See https://codereview.chromium.org/1118993002/#msg5 for more details.
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrString);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrString)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_TESTS_RESULTS_MODULES_BOOLEAN_OR_STRING_H_
diff --git a/third_party/blink/renderer/core/accessibility/ax_context.h b/third_party/blink/renderer/core/accessibility/ax_context.h
index 48606e0..28e62f6 100644
--- a/third_party/blink/renderer/core/accessibility/ax_context.h
+++ b/third_party/blink/renderer/core/accessibility/ax_context.h
@@ -19,6 +19,8 @@
 // Document::ExistingAXObjectCache will always return a valid
 // AXObjectCache if the document is still active.
 class CORE_EXPORT AXContext {
+  USING_FAST_MALLOC(AXContext);
+
  public:
   explicit AXContext(Document& document);
   virtual ~AXContext();
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h
index f2bab37d..d42c992 100644
--- a/third_party/blink/renderer/core/animation/animation.h
+++ b/third_party/blink/renderer/core/animation/animation.h
@@ -145,8 +145,8 @@
   bool Limited() const { return Limited(CurrentTimeInternal()); }
   bool FinishedInternal() const { return finished_; }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(finish, kFinish);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(cancel, kCancel);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(finish, kFinish)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(cancel, kCancel)
 
   const AtomicString& InterfaceName() const override;
   ExecutionContext* GetExecutionContext() const override;
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_update.h b/third_party/blink/renderer/core/animation/css/css_animation_update.h
index 21d5349..d0f7645 100644
--- a/third_party/blink/renderer/core/animation/css/css_animation_update.h
+++ b/third_party/blink/renderer/core/animation/css/css_animation_update.h
@@ -90,8 +90,8 @@
 
 }  // namespace blink
 
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::NewCSSAnimation);
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::UpdatedCSSAnimation);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::NewCSSAnimation)
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::UpdatedCSSAnimation)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/animation/non_interpolable_value.h b/third_party/blink/renderer/core/animation/non_interpolable_value.h
index 94ac28a..271eee8c 100644
--- a/third_party/blink/renderer/core/animation/non_interpolable_value.h
+++ b/third_party/blink/renderer/core/animation/non_interpolable_value.h
@@ -22,12 +22,12 @@
 // These macros provide safe downcasts of NonInterpolableValue subclasses with
 // debug assertions.
 // See CSSDefaultInterpolationType.cpp for example usage.
-#define DECLARE_NON_INTERPOLABLE_VALUE_TYPE() \
-  static Type static_type_;                   \
-  Type GetType() const final { return static_type_; }
+#define DECLARE_NON_INTERPOLABLE_VALUE_TYPE()         \
+  Type GetType() const final { return static_type_; } \
+  static Type static_type_
 
 #define DEFINE_NON_INTERPOLABLE_VALUE_TYPE(T) \
-  NonInterpolableValue::Type T::static_type_ = &T::static_type_;
+  NonInterpolableValue::Type T::static_type_ = &T::static_type_
 
 #define DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(T)               \
   inline bool Is##T(const NonInterpolableValue* value) {          \
diff --git a/third_party/blink/renderer/core/aom/accessible_node.h b/third_party/blink/renderer/core/aom/accessible_node.h
index 1115c51d..477b3e9 100644
--- a/third_party/blink/renderer/core/aom/accessible_node.h
+++ b/third_party/blink/renderer/core/aom/accessible_node.h
@@ -347,14 +347,13 @@
   const AtomicString& InterfaceName() const override;
   ExecutionContext* GetExecutionContext() const override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessibleclick, kAccessibleclick);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessiblecontextmenu,
-                                  kAccessiblecontextmenu);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessibledecrement, kAccessibledecrement);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessiblefocus, kAccessiblefocus);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessibleincrement, kAccessibleincrement);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessibleclick, kAccessibleclick)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessiblecontextmenu, kAccessiblecontextmenu)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessibledecrement, kAccessibledecrement)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessiblefocus, kAccessiblefocus)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(accessibleincrement, kAccessibleincrement)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(accessiblescrollintoview,
-                                  kAccessiblescrollintoview);
+                                  kAccessiblescrollintoview)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/core/css/css_gradient_value.h b/third_party/blink/renderer/core/css/css_gradient_value.h
index 76807dd..443422f 100644
--- a/third_party/blink/renderer/core/css/css_gradient_value.h
+++ b/third_party/blink/renderer/core/css/css_gradient_value.h
@@ -85,7 +85,7 @@
 // We have to declare the VectorTraits specialization before CSSGradientValue
 // declares its inline capacity vector below.
 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(
-    blink::cssvalue::CSSGradientColorStop);
+    blink::cssvalue::CSSGradientColorStop)
 
 namespace blink {
 namespace cssvalue {
diff --git a/third_party/blink/renderer/core/css/css_property_name.h b/third_party/blink/renderer/core/css/css_property_name.h
index e7c2433c..0135d94 100644
--- a/third_party/blink/renderer/core/css/css_property_name.h
+++ b/third_party/blink/renderer/core/css/css_property_name.h
@@ -57,6 +57,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::CSSPropertyName);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::CSSPropertyName)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PROPERTY_NAME_H_
diff --git a/third_party/blink/renderer/core/css/css_property_source_data.h b/third_party/blink/renderer/core/css/css_property_source_data.h
index 0826d351..f74ec56 100644
--- a/third_party/blink/renderer/core/css/css_property_source_data.h
+++ b/third_party/blink/renderer/core/css/css_property_source_data.h
@@ -53,7 +53,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::SourceRange);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::SourceRange)
 
 namespace blink {
 
@@ -79,7 +79,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::CSSPropertySourceData);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::CSSPropertySourceData)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/css/css_property_value.h b/third_party/blink/renderer/core/css/css_property_value.h
index d956eb9d..85599a8 100644
--- a/third_party/blink/renderer/core/css/css_property_value.h
+++ b/third_party/blink/renderer/core/css/css_property_value.h
@@ -104,6 +104,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::CSSPropertyValue);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::CSSPropertyValue)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PROPERTY_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/element_rule_collector.h b/third_party/blink/renderer/core/css/element_rule_collector.h
index 9d697620..46c37f3c 100644
--- a/third_party/blink/renderer/core/css/element_rule_collector.h
+++ b/third_party/blink/renderer/core/css/element_rule_collector.h
@@ -90,7 +90,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MatchedRule);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MatchedRule)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/css/font_face_set.h b/third_party/blink/renderer/core/css/font_face_set.h
index 01eeb9d..53c0f1c44 100644
--- a/third_party/blink/renderer/core/css/font_face_set.h
+++ b/third_party/blink/renderer/core/css/font_face_set.h
@@ -44,9 +44,9 @@
                                                    ReadyProperty::kReady)) {}
   ~FontFaceSet() override = default;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(loading, kLoading);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone, kLoadingdone);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror, kLoadingerror);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(loading, kLoading)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone, kLoadingdone)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror, kLoadingerror)
 
   bool check(const String& font, const String& text, ExceptionState&);
   ScriptPromise load(ScriptState*, const String& font, const String& text);
diff --git a/third_party/blink/renderer/core/css/media_query_list.h b/third_party/blink/renderer/core/css/media_query_list.h
index b03ca059..a4b02a45 100644
--- a/third_party/blink/renderer/core/css/media_query_list.h
+++ b/third_party/blink/renderer/core/css/media_query_list.h
@@ -62,7 +62,7 @@
   String media() const;
   bool matches();
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
 
   // These two functions are provided for compatibility with JS code
   // written before the change listener became a DOM event.
diff --git a/third_party/blink/renderer/core/css/resolver/match_result.h b/third_party/blink/renderer/core/css/resolver/match_result.h
index a188cdde..522bb73 100644
--- a/third_party/blink/renderer/core/css/resolver/match_result.h
+++ b/third_party/blink/renderer/core/css/resolver/match_result.h
@@ -59,7 +59,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MatchedProperties);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MatchedProperties)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h
index 41c0281..c4eac93 100644
--- a/third_party/blink/renderer/core/css/rule_set.h
+++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -67,7 +67,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MinimalRuleData);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MinimalRuleData)
 
 namespace blink {
 
@@ -146,7 +146,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::RuleData);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::RuleData)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/css/selector_filter.h b/third_party/blink/renderer/core/css/selector_filter.h
index 0694efa..69d9b975 100644
--- a/third_party/blink/renderer/core/css/selector_filter.h
+++ b/third_party/blink/renderer/core/css/selector_filter.h
@@ -104,6 +104,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::SelectorFilter::ParentStackFrame);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::SelectorFilter::ParentStackFrame)
 
 #endif
diff --git a/third_party/blink/renderer/core/dom/abort_signal.h b/third_party/blink/renderer/core/dom/abort_signal.h
index 65b7563a..b6abfc3e 100644
--- a/third_party/blink/renderer/core/dom/abort_signal.h
+++ b/third_party/blink/renderer/core/dom/abort_signal.h
@@ -26,7 +26,7 @@
 
   // abort_signal.idl
   bool aborted() const { return aborted_flag_; }
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort)
 
   const AtomicString& InterfaceName() const override;
   ExecutionContext* GetExecutionContext() const override;
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 7e67d30..8ade6a4f 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -287,18 +287,18 @@
 
   // DOM methods & attributes for Document
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy, kBeforecopy);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut, kBeforecut);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste, kBeforepaste);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(freeze, kFreeze);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange, kPointerlockchange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror, kPointerlockerror);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(resume, kResume);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy, kBeforecopy)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut, kBeforecut)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste, kBeforepaste)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(freeze, kFreeze)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange, kPointerlockchange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror, kPointerlockerror)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(resume, kResume)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation,
-                                  kSecuritypolicyviolation);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(visibilitychange, kVisibilitychange);
+                                  kSecuritypolicyviolation)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(visibilitychange, kVisibilitychange)
 
   ViewportData& GetViewportData() const { return *viewport_data_; }
 
diff --git a/third_party/blink/renderer/core/dom/document_and_element_event_handlers.h b/third_party/blink/renderer/core/dom/document_and_element_event_handlers.h
index 84cad84..d820bef 100644
--- a/third_party/blink/renderer/core/dom/document_and_element_event_handlers.h
+++ b/third_party/blink/renderer/core/dom/document_and_element_event_handlers.h
@@ -14,9 +14,9 @@
   STATIC_ONLY(DocumentAndElementEventHandlers);
 
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(copy, kCopy);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cut, kCut);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(paste, kPaste);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(copy, kCopy)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cut, kCut)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(paste, kPaste)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index 019ab18e..0070e18 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -162,10 +162,10 @@
 
   Element(const QualifiedName& tag_name, Document*, ConstructionType);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy, kBeforecopy);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut, kBeforecut);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste, kBeforepaste);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy, kBeforecopy)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut, kBeforecut)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste, kBeforepaste)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch)
 
   bool hasAttribute(const QualifiedName&) const;
   const AtomicString& getAttribute(const QualifiedName&) const;
diff --git a/third_party/blink/renderer/core/dom/events/node_event_context.h b/third_party/blink/renderer/core/dom/events/node_event_context.h
index feb59f0..b9c93d3 100644
--- a/third_party/blink/renderer/core/dom/events/node_event_context.h
+++ b/third_party/blink/renderer/core/dom/events/node_event_context.h
@@ -77,6 +77,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NodeEventContext);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NodeEventContext)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_NODE_EVENT_CONTEXT_H_
diff --git a/third_party/blink/renderer/core/dom/events/registered_event_listener.h b/third_party/blink/renderer/core/dom/events/registered_event_listener.h
index 7cee60d2..1cb068a 100644
--- a/third_party/blink/renderer/core/dom/events/registered_event_listener.h
+++ b/third_party/blink/renderer/core/dom/events/registered_event_listener.h
@@ -96,6 +96,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::RegisteredEventListener);
+WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::RegisteredEventListener)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_REGISTERED_EVENT_LISTENER_H_
diff --git a/third_party/blink/renderer/core/dom/global_event_handlers.h b/third_party/blink/renderer/core/dom/global_event_handlers.h
index 056f5f8..76f33e7a 100644
--- a/third_party/blink/renderer/core/dom/global_event_handlers.h
+++ b/third_party/blink/renderer/core/dom/global_event_handlers.h
@@ -39,88 +39,88 @@
   STATIC_ONLY(GlobalEventHandlers);
 
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abort, kAbort);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(activateinvisible, kActivateinvisible);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(auxclick, kAuxclick);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(blur, kBlur);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cancel, kCancel);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplay, kCanplay);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplaythrough, kCanplaythrough);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(change, kChange);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(click, kClick);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(close, kClose);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(contextmenu, kContextmenu);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cuechange, kCuechange);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dblclick, kDblclick);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drag, kDrag);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragend, kDragend);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragenter, kDragenter);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragleave, kDragleave);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragover, kDragover);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragstart, kDragstart);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drop, kDrop);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(durationchange, kDurationchange);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(emptied, kEmptied);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ended, kEnded);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(focus, kFocus);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(formdata, kFormdata);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(gotpointercapture, kGotpointercapture);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(input, kInput);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(invalid, kInvalid);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keydown, kKeydown);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keypress, kKeypress);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keyup, kKeyup);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(load, kLoad);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadeddata, kLoadeddata);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadedmetadata, kLoadedmetadata);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadstart, kLoadstart);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abort, kAbort)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(activateinvisible, kActivateinvisible)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(auxclick, kAuxclick)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(blur, kBlur)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cancel, kCancel)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplay, kCanplay)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplaythrough, kCanplaythrough)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(change, kChange)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(click, kClick)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(close, kClose)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(contextmenu, kContextmenu)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cuechange, kCuechange)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dblclick, kDblclick)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drag, kDrag)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragend, kDragend)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragenter, kDragenter)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragleave, kDragleave)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragover, kDragover)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragstart, kDragstart)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drop, kDrop)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(durationchange, kDurationchange)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(emptied, kEmptied)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ended, kEnded)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(focus, kFocus)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(formdata, kFormdata)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(gotpointercapture, kGotpointercapture)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(input, kInput)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(invalid, kInvalid)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keydown, kKeydown)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keypress, kKeypress)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keyup, kKeyup)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(load, kLoad)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadeddata, kLoadeddata)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadedmetadata, kLoadedmetadata)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadstart, kLoadstart)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(lostpointercapture,
-                                         kLostpointercapture);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousedown, kMousedown);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseenter, kMouseenter);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseleave, kMouseleave);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousemove, kMousemove);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseout, kMouseout);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseover, kMouseover);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseup, kMouseup);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousewheel, kMousewheel);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(overscroll, kOverscroll);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pause, kPause);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(play, kPlay);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(playing, kPlaying);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointercancel, kPointercancel);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerdown, kPointerdown);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerenter, kPointerenter);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerleave, kPointerleave);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointermove, kPointermove);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerout, kPointerout);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerover, kPointerover);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerrawmove, kPointerrawmove);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerup, kPointerup);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress, kProgress);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange, kRatechange);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(reset, kReset);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(resize, kResize);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scrollend, kScrollend);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeked, kSeeked);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeking, kSeeking);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(select, kSelect);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(selectionchange, kSelectionchange);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(selectstart, kSelectstart);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(stalled, kStalled);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(submit, kSubmit);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(suspend, kSuspend);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(timeupdate, kTimeupdate);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(toggle, kToggle);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchcancel, kTouchcancel);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchend, kTouchend);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchmove, kTouchmove);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchstart, kTouchstart);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(volumechange, kVolumechange);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waiting, kWaiting);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(wheel, kWheel);
+                                         kLostpointercapture)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousedown, kMousedown)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseenter, kMouseenter)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseleave, kMouseleave)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousemove, kMousemove)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseout, kMouseout)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseover, kMouseover)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseup, kMouseup)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousewheel, kMousewheel)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(overscroll, kOverscroll)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pause, kPause)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(play, kPlay)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(playing, kPlaying)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointercancel, kPointercancel)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerdown, kPointerdown)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerenter, kPointerenter)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerleave, kPointerleave)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointermove, kPointermove)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerout, kPointerout)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerover, kPointerover)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerrawmove, kPointerrawmove)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerup, kPointerup)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress, kProgress)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange, kRatechange)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(reset, kReset)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(resize, kResize)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scrollend, kScrollend)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeked, kSeeked)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeking, kSeeking)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(select, kSelect)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(selectionchange, kSelectionchange)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(selectstart, kSelectstart)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(stalled, kStalled)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(submit, kSubmit)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(suspend, kSuspend)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(timeupdate, kTimeupdate)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(toggle, kToggle)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchcancel, kTouchcancel)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchend, kTouchend)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchmove, kTouchmove)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchstart, kTouchstart)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(volumechange, kVolumechange)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waiting, kWaiting)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(wheel, kWheel)
 };
 
 }  // namespace
diff --git a/third_party/blink/renderer/core/dom/qualified_name.h b/third_party/blink/renderer/core/dom/qualified_name.h
index 48ff247..0551faa2 100644
--- a/third_party/blink/renderer/core/dom/qualified_name.h
+++ b/third_party/blink/renderer/core/dom/qualified_name.h
@@ -223,7 +223,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::QualifiedName);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::QualifiedName)
 
 namespace WTF {
 
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
index a0a464f6..5fbe57f6 100644
--- a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
@@ -962,7 +962,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::InlineRunToApplyStyle);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::InlineRunToApplyStyle)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.h b/third_party/blink/renderer/core/editing/finder/text_finder.h
index 3c3b9ab..a3a330c 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.h
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.h
@@ -253,6 +253,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::TextFinder::FindMatch);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::TextFinder::FindMatch)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_FINDER_TEXT_FINDER_H_
diff --git a/third_party/blink/renderer/core/editing/serializers/serialization.cc b/third_party/blink/renderer/core/editing/serializers/serialization.cc
index bd2a502..e0e70f9b 100644
--- a/third_party/blink/renderer/core/editing/serializers/serialization.cc
+++ b/third_party/blink/renderer/core/editing/serializers/serialization.cc
@@ -96,7 +96,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::AttributeChange);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::AttributeChange)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc
index 2d84f0d..2c2b5e7 100644
--- a/third_party/blink/renderer/core/exported/web_view_test.cc
+++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -5767,4 +5767,15 @@
   histogram_tester.ExpectTotalCount(kHistogramName, 2);
 }
 
+TEST_F(WebViewTest, ForceDarkModeInvalidatesPaint) {
+  WebViewImpl* web_view = web_view_helper_.Initialize();
+  web_view->MainFrameWidget()->Resize(WebSize(500, 500));
+  UpdateAllLifecyclePhases();
+
+  Document* document = web_view->MainFrameImpl()->GetFrame()->GetDocument();
+  ASSERT_TRUE(document);
+  web_view->GetSettings()->SetForceDarkModeEnabled(true);
+  EXPECT_TRUE(document->GetLayoutView()->ShouldDoFullPaintInvalidation());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc b/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc
index d3db96b..60e36eb 100644
--- a/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc
+++ b/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc
@@ -14,8 +14,11 @@
 
 bool DOMFeaturePolicy::allowsFeature(const String& feature) const {
   if (GetDefaultFeatureNameMap().Contains(feature)) {
-    return GetPolicy()->IsFeatureEnabled(
-        GetDefaultFeatureNameMap().at(feature));
+    auto feature_name = GetDefaultFeatureNameMap().at(feature);
+    mojom::PolicyValueType feature_type =
+        GetPolicy()->GetFeatureList().at(feature_name).second;
+    PolicyValue value = PolicyValue::CreateMaxPolicyValue(feature_type);
+    return GetPolicy()->IsFeatureEnabled(feature_name, value);
   }
 
   AddWarningForUnrecognizedFeature(feature);
@@ -38,8 +41,12 @@
     return false;
   }
 
-  return GetPolicy()->IsFeatureEnabledForOrigin(
-      GetDefaultFeatureNameMap().at(feature), origin->ToUrlOrigin());
+  auto feature_name = GetDefaultFeatureNameMap().at(feature);
+  mojom::PolicyValueType feature_type =
+      GetPolicy()->GetFeatureList().at(feature_name).second;
+  PolicyValue value = PolicyValue::CreateMaxPolicyValue(feature_type);
+  return GetPolicy()->IsFeatureEnabledForOrigin(feature_name,
+                                                origin->ToUrlOrigin(), value);
 }
 
 Vector<String> DOMFeaturePolicy::features() const {
@@ -52,7 +59,11 @@
 Vector<String> DOMFeaturePolicy::allowedFeatures() const {
   Vector<String> allowed_features;
   for (const auto& entry : GetDefaultFeatureNameMap()) {
-    if (GetPolicy()->IsFeatureEnabled(entry.value))
+    auto feature_name = entry.value;
+    mojom::PolicyValueType feature_type =
+        GetPolicy()->GetFeatureList().at(feature_name).second;
+    PolicyValue value = PolicyValue::CreateMaxPolicyValue(feature_type);
+    if (GetPolicy()->IsFeatureEnabled(feature_name, value))
       allowed_features.push_back(entry.key);
   }
   return allowed_features;
@@ -61,14 +72,22 @@
 Vector<String> DOMFeaturePolicy::getAllowlistForFeature(
     const String& feature) const {
   if (GetDefaultFeatureNameMap().Contains(feature)) {
+    auto feature_name = GetDefaultFeatureNameMap().at(feature);
+    auto feature_type = GetPolicy()->GetFeatureList().at(feature_name).second;
+
     const FeaturePolicy::Allowlist allowlist =
-        GetPolicy()->GetAllowlistForFeature(
-            GetDefaultFeatureNameMap().at(feature));
-    if (allowlist.MatchesAll())
-      return Vector<String>({"*"});
+        GetPolicy()->GetAllowlistForFeature(feature_name);
+    auto values = allowlist.Values();
+    PolicyValue max_value = PolicyValue::CreateMaxPolicyValue(feature_type);
+    if (values.empty()) {
+      if (allowlist.GetFallbackValue().Type() !=
+              mojom::PolicyValueType::kNull &&
+          allowlist.GetFallbackValue() >= max_value)
+        return Vector<String>({"*"});
+    }
     Vector<String> result;
-    for (const auto& origin : allowlist.Origins()) {
-      result.push_back(WTF::String::FromUTF8(origin.Serialize().c_str()));
+    for (const auto& entry : values) {
+      result.push_back(WTF::String::FromUTF8(entry.first.Serialize().c_str()));
     }
     return result;
   }
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy.cc b/third_party/blink/renderer/core/feature_policy/feature_policy.cc
index 8a88251..107e3f2c 100644
--- a/third_party/blink/renderer/core/feature_policy/feature_policy.cc
+++ b/third_party/blink/renderer/core/feature_policy/feature_policy.cc
@@ -4,6 +4,8 @@
 #include "third_party/blink/renderer/core/feature_policy/feature_policy.h"
 
 #include <algorithm>
+#include <map>
+#include <utility>
 
 #include "base/metrics/histogram_macros.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -112,6 +114,8 @@
       }
 
       mojom::FeaturePolicyFeature feature = feature_names.at(feature_name);
+      mojom::PolicyValueType feature_type =
+          FeaturePolicy::GetDefaultFeatureList().at(feature).second;
       // If a policy has already been specified for the current feature, drop
       // the new policy.
       if (features_specified.QuickGet(static_cast<int>(feature)))
@@ -132,11 +136,11 @@
                                   feature);
       }
 
-      ParsedFeaturePolicyDeclaration allowlist;
-      allowlist.feature = feature;
+      ParsedFeaturePolicyDeclaration allowlist(feature, feature_type);
       features_specified.QuickSet(static_cast<int>(feature));
-      std::vector<url::Origin> origins;
-      // If a policy entry has no (optional) values (e,g,
+      std::map<url::Origin, PolicyValue> values;
+      PolicyValue value = PolicyValue::CreateMaxPolicyValue(feature_type);
+      // If a policy entry has no listed origins (e.g. "feature_name1" in
       // allow="feature_name1; feature_name2 value"), enable the feature for:
       //     a. |self_origin|, if we are parsing a header policy (i.e.,
       //       |src_origin| is null);
@@ -145,11 +149,11 @@
       //     c. the opaque origin of the frame, if |src_origin| is opaque.
       if (tokens.size() == 1) {
         if (!src_origin) {
-          origins.push_back(self_origin->ToUrlOrigin());
+          values[self_origin->ToUrlOrigin()] = value;
         } else if (!src_origin->IsOpaque()) {
-          origins.push_back(src_origin->ToUrlOrigin());
+          values[src_origin->ToUrlOrigin()] = value;
         } else {
-          allowlist.matches_opaque_src = true;
+          allowlist.opaque_value = value;
         }
       }
 
@@ -159,7 +163,7 @@
           continue;
         }
         if (EqualIgnoringASCIICase(tokens[i], "'self'")) {
-          origins.push_back(self_origin->ToUrlOrigin());
+          values[self_origin->ToUrlOrigin()] = value;
         } else if (src_origin && EqualIgnoringASCIICase(tokens[i], "'src'")) {
           // Only the iframe allow attribute can define |src_origin|.
           // When parsing feature policy header, 'src' is disallowed and
@@ -167,32 +171,29 @@
           // If the iframe will have an opaque origin (for example, if it is
           // sandboxed, or has a data: URL), then 'src' needs to refer to the
           // opaque origin of the frame, which is not known yet. In this case,
-          // the |matches_opaque_src| flag on the declaration is set, rather
-          // than adding an origin to the allowlist.
+          // the |opaque_value| on the declaration is set, rather than adding
+          // an origin to the allowlist.
           if (src_origin->IsOpaque()) {
-            allowlist.matches_opaque_src = true;
+            allowlist.opaque_value = value;
           } else {
-            origins.push_back(src_origin->ToUrlOrigin());
+            values[src_origin->ToUrlOrigin()] = value;
           }
         } else if (EqualIgnoringASCIICase(tokens[i], "'none'")) {
           continue;
         } else if (tokens[i] == "*") {
-          allowlist.matches_all_origins = true;
-          origins.clear();
+          allowlist.fallback_value.SetToMax();
+          allowlist.opaque_value.SetToMax();
           break;
         } else {
           scoped_refptr<SecurityOrigin> target_origin =
               SecurityOrigin::CreateFromString(tokens[i]);
           if (!target_origin->IsOpaque())
-            origins.push_back(target_origin->ToUrlOrigin());
+            values[target_origin->ToUrlOrigin()] = value;
           else if (messages)
             messages->push_back("Unrecognized origin: '" + tokens[i] + "'.");
         }
       }
-      std::sort(origins.begin(), origins.end());
-      auto new_end = std::unique(origins.begin(), origins.end());
-      origins.erase(new_end, origins.end());
-      allowlist.origins = std::move(origins);
+      allowlist.values = std::move(values);
       allowlists.push_back(allowlist);
     }
   }
@@ -223,10 +224,9 @@
                                  ParsedFeaturePolicy& policy) {
   if (IsFeatureDeclared(feature, policy))
     return false;
-  ParsedFeaturePolicyDeclaration allowlist;
-  allowlist.feature = feature;
-  allowlist.matches_all_origins = false;
-  allowlist.matches_opaque_src = false;
+  blink::mojom::PolicyValueType feature_type =
+      blink::FeaturePolicy::GetDefaultFeatureList().at(feature).second;
+  ParsedFeaturePolicyDeclaration allowlist(feature, feature_type);
   policy.push_back(allowlist);
   return true;
 }
@@ -235,10 +235,11 @@
                                         ParsedFeaturePolicy& policy) {
   if (IsFeatureDeclared(feature, policy))
     return false;
-  ParsedFeaturePolicyDeclaration allowlist;
-  allowlist.feature = feature;
-  allowlist.matches_all_origins = true;
-  allowlist.matches_opaque_src = true;
+  blink::mojom::PolicyValueType feature_type =
+      blink::FeaturePolicy::GetDefaultFeatureList().at(feature).second;
+  ParsedFeaturePolicyDeclaration allowlist(feature, feature_type);
+  allowlist.fallback_value.SetToMax();
+  allowlist.opaque_value.SetToMax();
   policy.push_back(allowlist);
   return true;
 }
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc b/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc
index 083afa2..df86cd9 100644
--- a/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc
+++ b/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/core/feature_policy/feature_policy.h"
 
+#include <map>
+
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/loader/empty_clients.h"
@@ -78,10 +80,14 @@
   url::Origin expected_url_origin_b_ = url::Origin::Create(GURL(ORIGIN_B));
   url::Origin expected_url_origin_c_ = url::Origin::Create(GURL(ORIGIN_C));
 
+  // TODO(loonybear): Add a case for non-bool type feature.
   const FeatureNameMap test_feature_name_map = {
       {"fullscreen", blink::mojom::FeaturePolicyFeature::kFullscreen},
       {"payment", blink::mojom::FeaturePolicyFeature::kPayment},
       {"geolocation", blink::mojom::FeaturePolicyFeature::kGeolocation}};
+
+  const PolicyValue min_value = PolicyValue(false);
+  const PolicyValue max_value = PolicyValue(true);
 };
 
 TEST_F(FeaturePolicyParserTest, ParseValidPolicy) {
@@ -100,7 +106,7 @@
     messages.clear();
     ParseFeaturePolicy(policy_string, origin_a_.get(), origin_b_.get(),
                        &messages, test_feature_name_map);
-    EXPECT_NE(0UL, messages.size());
+    EXPECT_LT(0UL, messages.size());
   }
 }
 
@@ -120,11 +126,11 @@
 
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_FALSE(parsed_policy[0].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(1UL, parsed_policy[0].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[0].origins[0].IsSameOriginWith(expected_url_origin_a_));
+  EXPECT_GE(min_value, parsed_policy[0].fallback_value);
+  EXPECT_GE(min_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(1UL, parsed_policy[0].values.size());
+  EXPECT_TRUE(parsed_policy[0].values.begin()->first.IsSameOriginWith(
+      expected_url_origin_a_));
 
   // Simple policy with *.
   parsed_policy =
@@ -133,9 +139,9 @@
   EXPECT_EQ(1UL, parsed_policy.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_TRUE(parsed_policy[0].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(0UL, parsed_policy[0].origins.size());
+  EXPECT_LE(max_value, parsed_policy[0].fallback_value);
+  EXPECT_LE(max_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(0UL, parsed_policy[0].values.size());
 
   // Complicated policy.
   parsed_policy = ParseFeaturePolicy(
@@ -146,23 +152,22 @@
   EXPECT_EQ(3UL, parsed_policy.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_TRUE(parsed_policy[0].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(0UL, parsed_policy[0].origins.size());
+  EXPECT_LE(max_value, parsed_policy[0].fallback_value);
+  EXPECT_LE(max_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(0UL, parsed_policy[0].values.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
-  EXPECT_FALSE(parsed_policy[1].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[1].matches_opaque_src);
-  EXPECT_EQ(2UL, parsed_policy[1].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[1].origins[0].IsSameOriginWith(expected_url_origin_b_));
-  EXPECT_TRUE(
-      parsed_policy[1].origins[1].IsSameOriginWith(expected_url_origin_c_));
+  EXPECT_GE(min_value, parsed_policy[1].fallback_value);
+  EXPECT_GE(min_value, parsed_policy[1].opaque_value);
+  EXPECT_EQ(2UL, parsed_policy[1].values.size());
+  auto it = parsed_policy[1].values.begin();
+  EXPECT_TRUE(it->first.IsSameOriginWith(expected_url_origin_b_));
+  EXPECT_TRUE((++it)->first.IsSameOriginWith(expected_url_origin_c_));
   EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
-  EXPECT_FALSE(parsed_policy[2].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[2].matches_opaque_src);
-  EXPECT_EQ(1UL, parsed_policy[2].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[2].origins[0].IsSameOriginWith(expected_url_origin_a_));
+  EXPECT_GE(min_value, parsed_policy[2].fallback_value);
+  EXPECT_GE(min_value, parsed_policy[2].opaque_value);
+  EXPECT_EQ(1UL, parsed_policy[2].values.size());
+  EXPECT_TRUE(parsed_policy[2].values.begin()->first.IsSameOriginWith(
+      expected_url_origin_a_));
 
   // Multiple policies.
   parsed_policy = ParseFeaturePolicy(
@@ -173,23 +178,22 @@
   EXPECT_EQ(3UL, parsed_policy.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_TRUE(parsed_policy[0].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(0UL, parsed_policy[0].origins.size());
+  EXPECT_LE(max_value, parsed_policy[0].fallback_value);
+  EXPECT_LE(max_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(0UL, parsed_policy[0].values.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
-  EXPECT_FALSE(parsed_policy[1].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[1].matches_opaque_src);
-  EXPECT_EQ(2UL, parsed_policy[1].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[1].origins[0].IsSameOriginWith(expected_url_origin_b_));
-  EXPECT_TRUE(
-      parsed_policy[1].origins[1].IsSameOriginWith(expected_url_origin_c_));
+  EXPECT_GE(min_value, parsed_policy[1].fallback_value);
+  EXPECT_GE(min_value, parsed_policy[1].opaque_value);
+  EXPECT_EQ(2UL, parsed_policy[1].values.size());
+  it = parsed_policy[1].values.begin();
+  EXPECT_TRUE(it->first.IsSameOriginWith(expected_url_origin_b_));
+  EXPECT_TRUE((++it)->first.IsSameOriginWith(expected_url_origin_c_));
   EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
-  EXPECT_FALSE(parsed_policy[2].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[2].matches_opaque_src);
-  EXPECT_EQ(1UL, parsed_policy[2].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[2].origins[0].IsSameOriginWith(expected_url_origin_a_));
+  EXPECT_GE(min_value, parsed_policy[2].fallback_value);
+  EXPECT_GE(min_value, parsed_policy[2].opaque_value);
+  EXPECT_EQ(1UL, parsed_policy[2].values.size());
+  EXPECT_TRUE(parsed_policy[2].values.begin()->first.IsSameOriginWith(
+      expected_url_origin_a_));
 
   // Header policies with no optional origin lists.
   parsed_policy =
@@ -198,23 +202,22 @@
   EXPECT_EQ(3UL, parsed_policy.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_FALSE(parsed_policy[0].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(1UL, parsed_policy[0].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[0].origins[0].IsSameOriginWith(expected_url_origin_a_));
+  EXPECT_GE(min_value, parsed_policy[0].fallback_value);
+  EXPECT_GE(min_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(1UL, parsed_policy[0].values.size());
+  EXPECT_TRUE(parsed_policy[0].values.begin()->first.IsSameOriginWith(
+      expected_url_origin_a_));
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
-  EXPECT_FALSE(parsed_policy[1].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[1].matches_opaque_src);
-  EXPECT_EQ(1UL, parsed_policy[1].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[1].origins[0].IsSameOriginWith(expected_url_origin_a_));
+  EXPECT_GE(min_value, parsed_policy[1].fallback_value);
+  EXPECT_GE(min_value, parsed_policy[1].opaque_value);
+  EXPECT_EQ(1UL, parsed_policy[1].values.size());
+  EXPECT_TRUE(parsed_policy[1].values.begin()->first.IsSameOriginWith(
+      expected_url_origin_a_));
   EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
-  EXPECT_FALSE(parsed_policy[2].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[2].matches_opaque_src);
-  EXPECT_EQ(1UL, parsed_policy[2].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[2].origins[0].IsSameOriginWith(expected_url_origin_a_));
+  EXPECT_GE(min_value, parsed_policy[2].opaque_value);
+  EXPECT_EQ(1UL, parsed_policy[2].values.size());
+  EXPECT_TRUE(parsed_policy[2].values.begin()->first.IsSameOriginWith(
+      expected_url_origin_a_));
 }
 
 TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectlyForOpaqueOrigins) {
@@ -237,9 +240,9 @@
 
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_FALSE(parsed_policy[0].matches_all_origins);
-  EXPECT_TRUE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(0UL, parsed_policy[0].origins.size());
+  EXPECT_GE(min_value, parsed_policy[0].fallback_value);
+  EXPECT_LE(max_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(0UL, parsed_policy[0].values.size());
 
   // Simple policy with 'src'.
   parsed_policy =
@@ -249,9 +252,9 @@
 
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_FALSE(parsed_policy[0].matches_all_origins);
-  EXPECT_TRUE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(0UL, parsed_policy[0].origins.size());
+  EXPECT_GE(min_value, parsed_policy[0].fallback_value);
+  EXPECT_LE(max_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(0UL, parsed_policy[0].values.size());
 
   // Simple policy with *.
   parsed_policy =
@@ -261,9 +264,9 @@
 
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_TRUE(parsed_policy[0].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(0UL, parsed_policy[0].origins.size());
+  EXPECT_LE(max_value, parsed_policy[0].fallback_value);
+  EXPECT_LE(max_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(0UL, parsed_policy[0].values.size());
 
   // Policy with explicit origins
   parsed_policy = ParseFeaturePolicy(
@@ -273,13 +276,12 @@
 
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_FALSE(parsed_policy[0].matches_all_origins);
-  EXPECT_FALSE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(2UL, parsed_policy[0].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[0].origins[0].IsSameOriginWith(expected_url_origin_b_));
-  EXPECT_TRUE(
-      parsed_policy[0].origins[1].IsSameOriginWith(expected_url_origin_c_));
+  EXPECT_GE(min_value, parsed_policy[0].fallback_value);
+  EXPECT_GE(min_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(2UL, parsed_policy[0].values.size());
+  auto it = parsed_policy[0].values.begin();
+  EXPECT_TRUE(it->first.IsSameOriginWith(expected_url_origin_b_));
+  EXPECT_TRUE((++it)->first.IsSameOriginWith(expected_url_origin_c_));
 
   // Policy with multiple origins, including 'src'.
   parsed_policy = ParseFeaturePolicy("geolocation https://example.net 'src'",
@@ -289,11 +291,11 @@
 
   EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
             parsed_policy[0].feature);
-  EXPECT_FALSE(parsed_policy[0].matches_all_origins);
-  EXPECT_TRUE(parsed_policy[0].matches_opaque_src);
-  EXPECT_EQ(1UL, parsed_policy[0].origins.size());
-  EXPECT_TRUE(
-      parsed_policy[0].origins[0].IsSameOriginWith(expected_url_origin_b_));
+  EXPECT_GE(min_value, parsed_policy[0].fallback_value);
+  EXPECT_LE(max_value, parsed_policy[0].opaque_value);
+  EXPECT_EQ(1UL, parsed_policy[0].values.size());
+  EXPECT_TRUE(parsed_policy[0].values.begin()->first.IsSameOriginWith(
+      expected_url_origin_b_));
 }
 
 // Test histogram counting the use of feature policies in header.
@@ -408,8 +410,9 @@
     if (result == policy.end())
       return false;
 
-    return result->feature == feature && result->matches_all_origins &&
-           result->matches_opaque_src && result->origins.empty();
+    return result->feature == feature && result->fallback_value >= max_value &&
+           result->opaque_value >= max_value && result->values.empty();
+    return true;
   }
 
   // Returns true if the policy contains a declaration for the feature which
@@ -423,20 +426,26 @@
     if (result == policy.end())
       return false;
 
-    return result->feature == feature && !result->matches_all_origins &&
-           !result->matches_opaque_src && result->origins.empty();
+    return result->feature == feature && result->fallback_value <= min_value &&
+           result->opaque_value <= min_value && result->values.empty();
+    return true;
   }
 
-  ParsedFeaturePolicy test_policy = {{mojom::FeaturePolicyFeature::kFullscreen,
-                                      false,
-                                      false,
-                                      {url_origin_a_, url_origin_b_}},
-                                     {mojom::FeaturePolicyFeature::kGeolocation,
-                                      false,
-                                      false,
-                                      {url_origin_a_}}};
+  const PolicyValue min_value = PolicyValue(false);
+  const PolicyValue max_value = PolicyValue(true);
+
+  ParsedFeaturePolicy test_policy = {
+      {mojom::FeaturePolicyFeature::kFullscreen,
+       std::map<url::Origin, PolicyValue>{{url_origin_a_, PolicyValue(true)},
+                                          {url_origin_b_, PolicyValue(true)}},
+       PolicyValue(false), PolicyValue(false)},
+      {mojom::FeaturePolicyFeature::kGeolocation,
+       std::map<url::Origin, PolicyValue>{{url_origin_a_, PolicyValue(true)}},
+       PolicyValue(false), PolicyValue(false)}};
+
   ParsedFeaturePolicy empty_policy = {};
 };
+
 TEST_F(FeaturePolicyMutationTest, TestIsFeatureDeclared) {
   EXPECT_TRUE(
       IsFeatureDeclared(mojom::FeaturePolicyFeature::kFullscreen, test_policy));
diff --git a/third_party/blink/renderer/core/fileapi/file_reader.h b/third_party/blink/renderer/core/fileapi/file_reader.h
index 379e7105..17ed1a4 100644
--- a/third_party/blink/renderer/core/fileapi/file_reader.h
+++ b/third_party/blink/renderer/core/fileapi/file_reader.h
@@ -93,12 +93,12 @@
   void DidFinishLoading() override;
   void DidFail(FileErrorCode) override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart, kLoadstart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(load, kLoad);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend, kLoadend);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart, kLoadstart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(load, kLoad)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend, kLoadend)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/core/frame/dom_visual_viewport.h b/third_party/blink/renderer/core/frame/dom_visual_viewport.h
index be5c2cb..6a9253be 100644
--- a/third_party/blink/renderer/core/frame/dom_visual_viewport.h
+++ b/third_party/blink/renderer/core/frame/dom_visual_viewport.h
@@ -68,8 +68,8 @@
   double height() const;
   double scale() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(resize, kResize);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(resize, kResize)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll)
 
  private:
   Member<LocalDOMWindow> window_;
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
index 7b4a71da..21ab263 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -249,19 +249,19 @@
 
   bool isSecureContext() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(animationend, kAnimationend);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(animationiteration, kAnimationiteration);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(animationstart, kAnimationstart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(transitionend, kTransitionend);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(animationend, kAnimationend)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(animationiteration, kAnimationiteration)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(animationstart, kAnimationstart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(transitionend, kTransitionend)
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, kWebkitAnimationStart);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, kWebkitAnimationStart)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration,
-                                  kWebkitAnimationIteration);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, kWebkitAnimationEnd);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, kWebkitTransitionEnd);
+                                  kWebkitAnimationIteration)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, kWebkitAnimationEnd)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, kWebkitTransitionEnd)
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange)
 
   void RegisterEventListenerObserver(EventListenerObserver*);
 
diff --git a/third_party/blink/renderer/core/frame/settings.cc b/third_party/blink/renderer/core/frame/settings.cc
index d8720f4..051c378 100644
--- a/third_party/blink/renderer/core/frame/settings.cc
+++ b/third_party/blink/renderer/core/frame/settings.cc
@@ -117,7 +117,6 @@
   } else {
     SetHighContrastMode(HighContrastMode::kOff);
   }
-  Invalidate(SettingsDelegate::kStyleChange);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5
index a8e41609..085700f 100644
--- a/third_party/blink/renderer/core/frame/settings.json5
+++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -901,20 +901,24 @@
       name: "highContrastMode",
       initial: "HighContrastMode::kOff",
       type: "HighContrastMode",
+      invalidate: "Paint",
     },
     {
       name: "highContrastGrayscale",
       initial: false,
+      invalidate: "Paint",
     },
     {
       name: "highContrastContrast",
       initial: 0,
       type: "double",
+      invalidate: "Paint",
     },
     {
       name: "highContrastImagePolicy",
       initial: "HighContrastImagePolicy::kFilterAll",
       type: "HighContrastImagePolicy",
+      invalidate: "Paint",
     },
     {
       name: "mediaDownloadInProductHelpEnabled",
diff --git a/third_party/blink/renderer/core/frame/settings_delegate.h b/third_party/blink/renderer/core/frame/settings_delegate.h
index 548edcf..7fc500ba 100644
--- a/third_party/blink/renderer/core/frame/settings_delegate.h
+++ b/third_party/blink/renderer/core/frame/settings_delegate.h
@@ -67,6 +67,7 @@
     kMediaControlsChange,
     kPluginsChange,
     kHighlightAdsChange,
+    kPaintChange,
   };
 
   virtual void SettingsChanged(ChangeType) = 0;
diff --git a/third_party/blink/renderer/core/frame/window_event_handlers.h b/third_party/blink/renderer/core/frame/window_event_handlers.h
index d1c9a72..07ab42dc 100644
--- a/third_party/blink/renderer/core/frame/window_event_handlers.h
+++ b/third_party/blink/renderer/core/frame/window_event_handlers.h
@@ -39,27 +39,25 @@
   STATIC_ONLY(WindowEventHandlers);
 
  public:
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(afterprint, kAfterprint);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeprint, kBeforeprint);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload, kBeforeunload);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange, kHashchange);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(languagechange,
-                                                kLanguagechange);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline, kOffline);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(online, kOnline);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pagehide, kPagehide);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pageshow, kPageshow);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(popstate, kPopstate);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(portalactivate,
-                                                kPortalactivate);
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(afterprint, kAfterprint)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeprint, kBeforeprint)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload, kBeforeunload)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange, kHashchange)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(languagechange, kLanguagechange)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline, kOffline)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(online, kOnline)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pagehide, kPagehide)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pageshow, kPageshow)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(popstate, kPopstate)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(portalactivate, kPortalactivate)
   DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(rejectionhandled,
-                                                kRejectionhandled);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage, kStorage);
+                                                kRejectionhandled)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage, kStorage)
   DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unhandledrejection,
-                                                kUnhandledrejection);
-  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload, kUnload);
+                                                kUnhandledrejection)
+  DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload, kUnload)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/fullscreen/document_fullscreen.h b/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
index 76e6ec3f..a0ef800 100644
--- a/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
+++ b/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
@@ -45,13 +45,13 @@
   static ScriptPromise exitFullscreen(ScriptState*, Document&);
   static void webkitExitFullscreen(Document&);
 
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenchange, kFullscreenchange);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenerror, kFullscreenerror);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenchange, kFullscreenchange)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenerror, kFullscreenerror)
 
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange,
-                                         kWebkitfullscreenchange);
+                                         kWebkitfullscreenchange)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror,
-                                         kWebkitfullscreenerror);
+                                         kWebkitfullscreenerror)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/fullscreen/element_fullscreen.h b/third_party/blink/renderer/core/fullscreen/element_fullscreen.h
index c2268f60..512bb78 100644
--- a/third_party/blink/renderer/core/fullscreen/element_fullscreen.h
+++ b/third_party/blink/renderer/core/fullscreen/element_fullscreen.h
@@ -23,16 +23,16 @@
                                          Element&,
                                          const FullscreenOptions*);
 
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenchange, kFullscreenchange);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenerror, kFullscreenerror);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenchange, kFullscreenchange)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenerror, kFullscreenerror)
 
   static void webkitRequestFullscreen(Element&);
   static void webkitRequestFullscreen(Element&, const FullscreenOptions*);
 
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange,
-                                         kWebkitfullscreenchange);
+                                         kWebkitfullscreenchange)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror,
-                                         kWebkitfullscreenerror);
+                                         kWebkitfullscreenerror)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index 9783ff8..43e0f412 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -66,7 +66,7 @@
 
   bool HasPendingActivity() const final;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange, kWebkitspeechchange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange, kWebkitspeechchange)
 
   bool ShouldAutocomplete() const final;
 
diff --git a/third_party/blink/renderer/core/html/html_body_element.h b/third_party/blink/renderer/core/html/html_body_element.h
index ef648e8..bf1c645 100644
--- a/third_party/blink/renderer/core/html/html_body_element.h
+++ b/third_party/blink/renderer/core/html/html_body_element.h
@@ -41,13 +41,13 @@
   explicit HTMLBodyElement(Document&);
   ~HTMLBodyElement() override;
 
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur, kBlur);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus, kFocus);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load, kLoad);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize, kResize);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange);
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur, kBlur)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus, kFocus)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load, kLoad)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize, kResize)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange)
 
  private:
   void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/third_party/blink/renderer/core/html/html_frame_element.cc b/third_party/blink/renderer/core/html/html_frame_element.cc
index 98d28bb8..b1357b6 100644
--- a/third_party/blink/renderer/core/html/html_frame_element.cc
+++ b/third_party/blink/renderer/core/html/html_frame_element.cc
@@ -90,9 +90,8 @@
   // unable to use the API, regardless of origin.
   // https://fullscreen.spec.whatwg.org/#model
   ParsedFeaturePolicy container_policy;
-  ParsedFeaturePolicyDeclaration allowlist;
-  allowlist.feature = mojom::FeaturePolicyFeature::kFullscreen;
-  allowlist.matches_all_origins = false;
+  ParsedFeaturePolicyDeclaration allowlist(
+      mojom::FeaturePolicyFeature::kFullscreen, mojom::PolicyValueType::kBool);
   container_policy.push_back(allowlist);
   return container_policy;
 }
diff --git a/third_party/blink/renderer/core/html/html_frame_element_test.cc b/third_party/blink/renderer/core/html/html_frame_element_test.cc
index 54a4cf8..2a9b23b 100644
--- a/third_party/blink/renderer/core/html/html_frame_element_test.cc
+++ b/third_party/blink/renderer/core/html/html_frame_element_test.cc
@@ -31,8 +31,8 @@
   // Fullscreen should be disabled in this frame
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
             container_policy[0].feature);
-  EXPECT_FALSE(container_policy[0].matches_all_origins);
-  EXPECT_EQ(0UL, container_policy[0].origins.size());
+  EXPECT_EQ(0UL, container_policy[0].values.size());
+  EXPECT_GE(PolicyValue(false), container_policy[0].fallback_value);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_frame_set_element.h b/third_party/blink/renderer/core/html/html_frame_set_element.h
index cea9891..c07a009 100644
--- a/third_party/blink/renderer/core/html/html_frame_set_element.h
+++ b/third_party/blink/renderer/core/html/html_frame_set_element.h
@@ -57,13 +57,13 @@
 
   bool HasNonInBodyInsertionMode() const override { return true; }
 
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur, kBlur);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus, kFocus);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load, kLoad);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize, kResize);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll);
-  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange);
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur, kBlur)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus, kFocus)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load, kLoad)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize, kResize)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll)
+  DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange)
 
  private:
   void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/third_party/blink/renderer/core/html/html_iframe_element_test.cc b/third_party/blink/renderer/core/html/html_iframe_element_test.cc
index bbb3632..f445107 100644
--- a/third_party/blink/renderer/core/html/html_iframe_element_test.cc
+++ b/third_party/blink/renderer/core/html/html_iframe_element_test.cc
@@ -19,6 +19,10 @@
       HTMLIFrameElement* element) {
     return element->GetOriginForFeaturePolicy();
   }
+
+ protected:
+  const PolicyValue min_value = PolicyValue(false);
+  const PolicyValue max_value = PolicyValue(true);
 };
 
 // Test that the correct origin is used when constructing the container policy,
@@ -196,9 +200,10 @@
   EXPECT_EQ(1UL, container_policy1.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
             container_policy1[0].feature);
-  EXPECT_FALSE(container_policy1[0].matches_all_origins);
-  EXPECT_EQ(1UL, container_policy1[0].origins.size());
-  EXPECT_EQ("http://example.net", container_policy1[0].origins[0].Serialize());
+  EXPECT_GE(min_value, container_policy1[0].fallback_value);
+  EXPECT_EQ(1UL, container_policy1[0].values.size());
+  EXPECT_EQ("http://example.net",
+            container_policy1[0].values.begin()->first.Serialize());
 
   frame_element->setAttribute(html_names::kAllowAttr, "payment; fullscreen");
   frame_element->UpdateContainerPolicyForTests();
@@ -213,12 +218,13 @@
   EXPECT_TRUE(
       container_policy2[0].feature == mojom::FeaturePolicyFeature::kPayment ||
       container_policy2[1].feature == mojom::FeaturePolicyFeature::kPayment);
-  EXPECT_FALSE(container_policy2[0].matches_all_origins);
-  EXPECT_EQ(1UL, container_policy2[0].origins.size());
-  EXPECT_EQ("http://example.net", container_policy2[0].origins[0].Serialize());
-  EXPECT_FALSE(container_policy2[1].matches_all_origins);
-  EXPECT_EQ(1UL, container_policy2[1].origins.size());
-  EXPECT_EQ("http://example.net", container_policy2[1].origins[0].Serialize());
+  EXPECT_EQ(1UL, container_policy2[0].values.size());
+  EXPECT_EQ("http://example.net",
+            container_policy2[0].values.begin()->first.Serialize());
+  EXPECT_GE(min_value, container_policy2[1].fallback_value);
+  EXPECT_EQ(1UL, container_policy2[1].values.size());
+  EXPECT_EQ("http://example.net",
+            container_policy2[1].values.begin()->first.Serialize());
 }
 
 // Sandboxing an iframe should result in a container policy with an item for
@@ -280,9 +286,9 @@
 
   const ParsedFeaturePolicyDeclaration item = *container_policy_item;
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, item.feature);
-  EXPECT_FALSE(item.matches_all_origins);
-  EXPECT_TRUE(item.matches_opaque_src);
-  EXPECT_EQ(0UL, item.origins.size());
+  EXPECT_GE(min_value, item.fallback_value);
+  EXPECT_LE(max_value, item.opaque_value);
+  EXPECT_EQ(0UL, item.values.size());
   RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(false);
 }
 
@@ -320,11 +326,11 @@
 
   const ParsedFeaturePolicyDeclaration item = *container_policy_item;
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, item.feature);
-  EXPECT_FALSE(item.matches_all_origins);
-  EXPECT_FALSE(item.matches_opaque_src);
-  EXPECT_EQ(1UL, item.origins.size());
-  EXPECT_FALSE(item.origins[0].opaque());
-  EXPECT_EQ("http://example.net", item.origins[0].Serialize());
+  EXPECT_GE(min_value, item.fallback_value);
+  EXPECT_GE(min_value, item.opaque_value);
+  EXPECT_EQ(1UL, item.values.size());
+  EXPECT_FALSE(item.values.begin()->first.opaque());
+  EXPECT_EQ("http://example.net", item.values.begin()->first.Serialize());
   RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(false);
 }
 
@@ -357,14 +363,13 @@
       frame_element->ConstructContainerPolicy(nullptr);
   EXPECT_EQ(2UL, container_policy.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[0].feature);
-  EXPECT_FALSE(container_policy[0].matches_all_origins);
-  EXPECT_EQ(1UL, container_policy[0].origins.size());
-  EXPECT_TRUE(container_policy[0].origins[0].IsSameOriginWith(
+  EXPECT_GE(min_value, container_policy[0].fallback_value);
+  EXPECT_EQ(1UL, container_policy[0].values.size());
+  EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
   EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[1].feature);
-  EXPECT_FALSE(container_policy[1].matches_all_origins);
-  EXPECT_EQ(1UL, container_policy[1].origins.size());
-  EXPECT_TRUE(container_policy[1].origins[0].IsSameOriginWith(
+  EXPECT_EQ(1UL, container_policy[1].values.size());
+  EXPECT_TRUE(container_policy[1].values.begin()->first.IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
 }
 
@@ -384,7 +389,7 @@
   EXPECT_EQ(1UL, container_policy.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
             container_policy[0].feature);
-  EXPECT_TRUE(container_policy[0].matches_all_origins);
+  EXPECT_LE(max_value, container_policy[0].fallback_value);
 }
 
 // Test the ConstructContainerPolicy method when the "allowpaymentrequest"
@@ -404,12 +409,11 @@
       frame_element->ConstructContainerPolicy(nullptr);
   EXPECT_EQ(2UL, container_policy.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[0].feature);
-  EXPECT_FALSE(container_policy[0].matches_all_origins);
-  EXPECT_EQ(1UL, container_policy[0].origins.size());
-  EXPECT_TRUE(container_policy[0].origins[0].IsSameOriginWith(
+  EXPECT_GE(min_value, container_policy[0].fallback_value);
+  EXPECT_EQ(1UL, container_policy[0].values.size());
+  EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
   EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[1].feature);
-  EXPECT_TRUE(container_policy[1].matches_all_origins);
 }
 
 // Test the ConstructContainerPolicy method when both "allowfullscreen" and
@@ -434,18 +438,16 @@
       frame_element->ConstructContainerPolicy(nullptr);
   EXPECT_EQ(3UL, container_policy.size());
   EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[0].feature);
-  EXPECT_FALSE(container_policy[0].matches_all_origins);
-  EXPECT_EQ(1UL, container_policy[0].origins.size());
-  EXPECT_TRUE(container_policy[0].origins[0].IsSameOriginWith(
+  EXPECT_GE(min_value, container_policy[0].fallback_value);
+  EXPECT_EQ(1UL, container_policy[0].values.size());
+  EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
   EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[1].feature);
-  EXPECT_FALSE(container_policy[1].matches_all_origins);
-  EXPECT_EQ(1UL, container_policy[1].origins.size());
-  EXPECT_TRUE(container_policy[1].origins[0].IsSameOriginWith(
+  EXPECT_EQ(1UL, container_policy[1].values.size());
+  EXPECT_TRUE(container_policy[1].values.begin()->first.IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
   EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
             container_policy[2].feature);
-  EXPECT_TRUE(container_policy[2].matches_all_origins);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc
index 788ae56..e9d6ca5 100644
--- a/third_party/blink/renderer/core/html/html_plugin_element.cc
+++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -316,9 +316,8 @@
   // origin.
   // https://fullscreen.spec.whatwg.org/#model
   ParsedFeaturePolicy container_policy;
-  ParsedFeaturePolicyDeclaration allowlist;
-  allowlist.feature = mojom::FeaturePolicyFeature::kFullscreen;
-  allowlist.matches_all_origins = false;
+  ParsedFeaturePolicyDeclaration allowlist(
+      mojom::FeaturePolicyFeature::kFullscreen, mojom::PolicyValueType::kBool);
   container_policy.push_back(allowlist);
   return container_policy;
 }
diff --git a/third_party/blink/renderer/core/html/parser/html_construction_site.h b/third_party/blink/renderer/core/html/parser/html_construction_site.h
index 05dfa7bc..fe5e571 100644
--- a/third_party/blink/renderer/core/html/parser/html_construction_site.h
+++ b/third_party/blink/renderer/core/html/parser/html_construction_site.h
@@ -76,7 +76,7 @@
 }  // namespace blink
 
 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
-    blink::HTMLConstructionSiteTask);
+    blink::HTMLConstructionSiteTask)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h b/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
index 168b2cff..7d8e16b 100644
--- a/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
+++ b/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
@@ -146,6 +146,6 @@
 }  // namespace blink
 
 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(
-    blink::HTMLFormattingElementList::Entry);
+    blink::HTMLFormattingElementList::Entry)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_HTML_FORMATTING_ELEMENT_LIST_H_
diff --git a/third_party/blink/renderer/core/html/track/text_track.h b/third_party/blink/renderer/core/html/track/text_track.h
index 6117240..9b96c851 100644
--- a/third_party/blink/renderer/core/html/track/text_track.h
+++ b/third_party/blink/renderer/core/html/track/text_track.h
@@ -111,7 +111,7 @@
   void CueWillChange(TextTrackCue*);
   void CueDidChange(TextTrackCue*, bool update_cue_index);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(cuechange, kCuechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(cuechange, kCuechange)
 
   TextTrackType TrackType() const { return track_type_; }
 
diff --git a/third_party/blink/renderer/core/html/track/text_track_cue.h b/third_party/blink/renderer/core/html/track/text_track_cue.h
index 83efced..176febe 100644
--- a/third_party/blink/renderer/core/html/track/text_track_cue.h
+++ b/third_party/blink/renderer/core/html/track/text_track_cue.h
@@ -94,8 +94,8 @@
   virtual String ToString() const = 0;
 #endif
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(enter, kEnter);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(exit, kExit);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(enter, kEnter)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(exit, kExit)
 
   void Trace(Visitor*) override;
 
diff --git a/third_party/blink/renderer/core/html/track/text_track_list.h b/third_party/blink/renderer/core/html/track/text_track_list.h
index 551b04a..841e0d88 100644
--- a/third_party/blink/renderer/core/html/track/text_track_list.h
+++ b/third_party/blink/renderer/core/html/track/text_track_list.h
@@ -63,9 +63,9 @@
   const AtomicString& InterfaceName() const override;
   ExecutionContext* GetExecutionContext() const override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack, kAddtrack);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack, kRemovetrack);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack, kAddtrack)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack, kRemovetrack)
 
   HTMLMediaElement* Owner() const;
 
diff --git a/third_party/blink/renderer/core/html/track/track_list_base.h b/third_party/blink/renderer/core/html/track/track_list_base.h
index 93b747f..6b9dca3 100644
--- a/third_party/blink/renderer/core/html/track/track_list_base.h
+++ b/third_party/blink/renderer/core/html/track/track_list_base.h
@@ -37,9 +37,9 @@
     return nullptr;
   }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack, kAddtrack);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack, kRemovetrack);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack, kAddtrack)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack, kRemovetrack)
 
   // EventTarget interface
   ExecutionContext* GetExecutionContext() const override {
diff --git a/third_party/blink/renderer/core/input/event_handling_util.h b/third_party/blink/renderer/core/input/event_handling_util.h
index b5e8ead..74199c5e 100644
--- a/third_party/blink/renderer/core/input/event_handling_util.h
+++ b/third_party/blink/renderer/core/input/event_handling_util.h
@@ -72,6 +72,6 @@
 }  // namespace blink
 
 WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(
-    blink::event_handling_util::PointerEventTarget);
+    blink::event_handling_util::PointerEventTarget)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_EVENT_HANDLING_UTIL_H_
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn
index 9314c7e..b150a53 100644
--- a/third_party/blink/renderer/core/layout/BUILD.gn
+++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -388,6 +388,8 @@
     "ng/inline/ng_text_fragment.h",
     "ng/inline/ng_text_fragment_builder.cc",
     "ng/inline/ng_text_fragment_builder.h",
+    "ng/layout_box_utils.cc",
+    "ng/layout_box_utils.h",
     "ng/layout_ng_block_flow.cc",
     "ng/layout_ng_block_flow.h",
     "ng/layout_ng_fieldset.cc",
diff --git a/third_party/blink/renderer/core/layout/hit_test_cache.h b/third_party/blink/renderer/core/layout/hit_test_cache.h
index 4cd439c..9274fbc0 100644
--- a/third_party/blink/renderer/core/layout/hit_test_cache.h
+++ b/third_party/blink/renderer/core/layout/hit_test_cache.h
@@ -92,6 +92,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::HitTestCacheEntry);
+WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::HitTestCacheEntry)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_HIT_TEST_CACHE_H_
diff --git a/third_party/blink/renderer/core/layout/hit_test_result.h b/third_party/blink/renderer/core/layout/hit_test_result.h
index 54ab7bc..2e8608a 100644
--- a/third_party/blink/renderer/core/layout/hit_test_result.h
+++ b/third_party/blink/renderer/core/layout/hit_test_result.h
@@ -209,6 +209,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::HitTestResult);
+WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::HitTestResult)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_HIT_TEST_RESULT_H_
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 1014d1b..17c5754 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -3475,6 +3475,7 @@
            ToLayoutCustom(containing_block)->IsLoaded()) &&
          !containing_block->HasOverridePercentageResolutionBlockSize() &&
          !containing_block->IsLayoutGrid() &&
+         !containing_block->IsFlexibleBoxIncludingDeprecatedAndNG() &&
          containing_block->StyleRef().LogicalHeight().IsAuto();
 }
 
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 f265434..eea8713 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
@@ -725,11 +725,14 @@
       !IsOutOfFlowPositionedWithImplicitHeight(this))
     return true;
 
-  if (GetDocument().InQuirksMode())
-    return false;
-
-  if (cb)
-    return !cb->HasDefiniteLogicalHeight();
+  if (cb) {
+    // We need the containing block to have a definite block-size in order to
+    // resolve the block-size of the descendant, except when in quirks mode.
+    // Flexboxes follow strict behavior even in quirks mode, though.
+    if (!GetDocument().InQuirksMode() ||
+        cb->IsFlexibleBoxIncludingDeprecatedAndNG())
+      return !cb->HasDefiniteLogicalHeight();
+  }
 
   return false;
 }
diff --git a/third_party/blink/renderer/core/layout/layout_geometry_map_step.h b/third_party/blink/renderer/core/layout/layout_geometry_map_step.h
index 02aac84..661073cb 100644
--- a/third_party/blink/renderer/core/layout/layout_geometry_map_step.h
+++ b/third_party/blink/renderer/core/layout/layout_geometry_map_step.h
@@ -69,7 +69,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
-    blink::LayoutGeometryMapStep);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::LayoutGeometryMapStep)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_GEOMETRY_MAP_STEP_H_
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc
index 8361000e..56e2005 100644
--- a/third_party/blink/renderer/core/layout/layout_image.cc
+++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -247,6 +247,8 @@
     return;
 
   // Check for oversized-images policy.
+  // TODO(loonybear): Support oversized-images policy on other image types
+  // in addition to HTMLImageElement (crbug.com/930281).
   if (IsHTMLImageElement(GetNode()) && image_resource_->CachedImage()) {
     is_oversized_image_ = CheckForOversizedImagesPolicy(
         GetDocument(), image_resource_->CachedImage(), this);
@@ -466,12 +468,27 @@
          ToHTMLImageElement(GetNode())->IsImagePolicyViolated();
 }
 
+void LayoutImage::ReportImagePolicyViolation() const {
+  if (is_oversized_image_) {
+    auto state = GetDocument().GetFeatureEnabledState(
+        mojom::FeaturePolicyFeature::kOversizedImages);
+    GetDocument().ReportFeaturePolicyViolation(
+        mojom::FeaturePolicyFeature::kOversizedImages,
+        state == FeatureEnabledState::kReportOnly
+            ? mojom::FeaturePolicyDisposition::kReport
+            : mojom::FeaturePolicyDisposition::kEnforce);
+  }
+  // TODO(loonybear): move unsized-media violation here.
+}
+
 void LayoutImage::UpdateAfterLayout() {
   LayoutBox::UpdateAfterLayout();
   Node* node = GetNode();
 
+  // Check for oversized-images policy.
+  // TODO(loonybear): Support oversized-images policy on other image types
+  // in addition to HTMLImageElement.
   if (auto* image_element = ToHTMLImageElementOrNull(node)) {
-    // Check for oversized-images policy.
     if (image_resource_ && image_resource_->CachedImage()) {
       is_oversized_image_ = CheckForOversizedImagesPolicy(
           GetDocument(), image_resource_->CachedImage(), this);
diff --git a/third_party/blink/renderer/core/layout/layout_image.h b/third_party/blink/renderer/core/layout/layout_image.h
index 3838757c..486308f 100644
--- a/third_party/blink/renderer/core/layout/layout_image.h
+++ b/third_party/blink/renderer/core/layout/layout_image.h
@@ -92,6 +92,10 @@
   // https://github.com/WICG/feature-policy/blob/master/policies/optimized-images.md
   bool IsImagePolicyViolated() const;
 
+  // For image policies that require layout input, report the policy violation
+  // every time when the image is being repainted.
+  void ReportImagePolicyViolation() const;
+
   void UpdateAfterLayout() override;
 
  protected:
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
index e8d970d7..87b3e4ca 100644
--- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
+++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
@@ -389,6 +389,6 @@
 }  // namespace blink
 
 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
-    blink::NGExclusionSpaceInternal::NGShelfEdge);
+    blink::NGExclusionSpaceInternal::NGShelfEdge)
 
 #endif  // NGExclusionSpace_h
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
index 4062179..f875a49 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -1025,7 +1025,8 @@
   NGLineBreaker line_breaker(
       node, mode, space, line_opportunity, empty_leading_floats,
       /* handled_leading_floats_index */ 0u,
-      /* break_token */ nullptr, &empty_exclusion_space, &floats_for_min_max);
+      /* break_token */ nullptr, &empty_exclusion_space,
+      input.percentage_resolution_block_size, &floats_for_min_max);
   do {
     floats_for_min_max.Shrink(0);
 
@@ -1053,9 +1054,10 @@
       NGBlockNode float_node(ToLayoutBox(floating_object));
       const ComputedStyle& float_style = float_node.Style();
 
-      MinMaxSizeInput zero_input;  // Floats don't intrude into floats.
+      // Floats don't intrude into floats.
+      MinMaxSizeInput float_input(input.percentage_resolution_block_size);
       MinMaxSize child_sizes =
-          ComputeMinAndMaxContentContribution(style, float_node, zero_input);
+          ComputeMinAndMaxContentContribution(style, float_node, float_input);
       LayoutUnit child_inline_margins =
           ComputeMinMaxMargins(style, float_node).InlineSum();
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
index 73d52b96..4371fbcb 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
@@ -112,6 +112,12 @@
     return node;
   }
 
+  MinMaxSize ComputeMinMaxSize(NGInlineNode node) {
+    return node.ComputeMinMaxSize(
+        node.Style().GetWritingMode(),
+        MinMaxSizeInput(/* percentage_resolution_block_size */ LayoutUnit()));
+  }
+
   void CreateLine(
       NGInlineNode node,
       Vector<scoped_refptr<const NGPhysicalTextFragment>>* fragments_out) {
@@ -461,8 +467,7 @@
   LoadAhem();
   SetupHtml("t", "<div id=t style='font:10px Ahem'>AB CDEF</div>");
   NGInlineNodeForTest node = CreateInlineNode();
-  MinMaxSize sizes =
-      node.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
+  MinMaxSize sizes = ComputeMinMaxSize(node);
   EXPECT_EQ(40, sizes.min_size);
   EXPECT_EQ(70, sizes.max_size);
 }
@@ -471,8 +476,7 @@
   LoadAhem();
   SetupHtml("t", "<div id=t style='font:10px Ahem'>A B<span>C D</span></div>");
   NGInlineNodeForTest node = CreateInlineNode();
-  MinMaxSize sizes =
-      node.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
+  MinMaxSize sizes = ComputeMinMaxSize(node);
   // |min_content| should be the width of "BC" because there is an element
   // boundary between "B" and "C" but no break opportunities.
   EXPECT_EQ(20, sizes.min_size);
@@ -491,8 +495,7 @@
   )HTML");
 
   NGInlineNodeForTest node = CreateInlineNode();
-  MinMaxSize sizes =
-      node.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
+  MinMaxSize sizes = ComputeMinMaxSize(node);
 
   EXPECT_EQ(50, sizes.min_size);
   EXPECT_EQ(130, sizes.max_size);
@@ -511,8 +514,7 @@
   )HTML");
 
   NGInlineNodeForTest node = CreateInlineNode();
-  MinMaxSize sizes =
-      node.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
+  MinMaxSize sizes = ComputeMinMaxSize(node);
 
   EXPECT_EQ(50, sizes.min_size);
   EXPECT_EQ(160, sizes.max_size);
@@ -931,8 +933,7 @@
   // Inline block with auto-size calls |ComputeMinMaxSize|, which may call
   // |CollectInlines|. Emulate it to ensure it does not let tests to fail.
   GetDocument().UpdateStyleAndLayoutTree();
-  NGInlineNode(layout_block_flow_)
-      .ComputeMinMaxSize(layout_block_flow_->StyleRef().GetWritingMode(), {});
+  ComputeMinMaxSize(NGInlineNode(layout_block_flow_));
 
   auto lines = MarkLineBoxesDirty();
   EXPECT_FALSE(lines[0]->IsDirty());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
index 7702b04ed..03f50e4f 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
@@ -237,6 +237,6 @@
 }  // namespace blink
 
 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
-    blink::NGLineBoxFragmentBuilder::Child);
+    blink::NGLineBoxFragmentBuilder::Child)
 
 #endif  // NGLineBoxFragmentBuilder
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
index 7f7e9f45..372b638 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -64,15 +64,17 @@
 
 }  // namespace
 
-NGLineBreaker::NGLineBreaker(NGInlineNode node,
-                             NGLineBreakerMode mode,
-                             const NGConstraintSpace& space,
-                             const NGLineLayoutOpportunity& line_opportunity,
-                             const NGPositionedFloatVector& leading_floats,
-                             unsigned handled_leading_floats_index,
-                             const NGInlineBreakToken* break_token,
-                             NGExclusionSpace* exclusion_space,
-                             Vector<LayoutObject*>* out_floats_for_min_max)
+NGLineBreaker::NGLineBreaker(
+    NGInlineNode node,
+    NGLineBreakerMode mode,
+    const NGConstraintSpace& space,
+    const NGLineLayoutOpportunity& line_opportunity,
+    const NGPositionedFloatVector& leading_floats,
+    unsigned handled_leading_floats_index,
+    const NGInlineBreakToken* break_token,
+    NGExclusionSpace* exclusion_space,
+    LayoutUnit percentage_resolution_block_size_for_min_max,
+    Vector<LayoutObject*>* out_floats_for_min_max)
     : line_opportunity_(line_opportunity),
       node_(node),
       is_first_formatted_line_((!break_token || (!break_token->ItemIndex() &&
@@ -90,8 +92,10 @@
       spacing_(items_data_.text_content),
       leading_floats_(leading_floats),
       handled_leading_floats_index_(handled_leading_floats_index),
-      out_floats_for_min_max_(out_floats_for_min_max),
-      base_direction_(node_.BaseDirection()) {
+      base_direction_(node_.BaseDirection()),
+      percentage_resolution_block_size_for_min_max_(
+          percentage_resolution_block_size_for_min_max),
+      out_floats_for_min_max_(out_floats_for_min_max) {
   break_iterator_.SetBreakSpace(BreakSpaceType::kBeforeSpaceRun);
 
   if (break_token) {
@@ -1022,7 +1026,7 @@
             .InlineSize();
   } else {
     NGBlockNode child(ToLayoutBox(item.GetLayoutObject()));
-    MinMaxSizeInput input;
+    MinMaxSizeInput input(percentage_resolution_block_size_for_min_max_);
     MinMaxSize sizes =
         ComputeMinAndMaxContentContribution(node_.Style(), child, input);
     item_result->inline_size = mode_ == NGLineBreakerMode::kMinContent
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
index ae08322..c53f005 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -40,6 +40,8 @@
                 unsigned handled_leading_floats_index,
                 const NGInlineBreakToken*,
                 NGExclusionSpace*,
+                LayoutUnit percentage_resolution_block_size_for_min_max =
+                    NGSizeIndefinite,
                 Vector<LayoutObject*>* out_floats_for_min_max = nullptr);
   ~NGLineBreaker();
 
@@ -243,8 +245,6 @@
   unsigned leading_floats_index_ = 0u;
   unsigned handled_leading_floats_index_;
 
-  Vector<LayoutObject*>* out_floats_for_min_max_;
-
   // Keep the last item |HandleTextForFastMinContent()| has handled. This is
   // used to fallback the last word to |HandleText()|.
   const NGInlineItem* fast_min_content_item_ = nullptr;
@@ -253,6 +253,11 @@
   // This is copied from NGInlineNode, then updated after each forced line break
   // if 'unicode-bidi: plaintext'.
   TextDirection base_direction_;
+
+  // During the min/max size calculation we need a special percentage
+  // resolution block-size to pass to children/pass to children.
+  LayoutUnit percentage_resolution_block_size_for_min_max_;
+  Vector<LayoutObject*>* out_floats_for_min_max_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
index 01005a2d..861fd96 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -511,7 +511,9 @@
     <div id=container>12345 6789 </div>
   )HTML");
 
-  auto size = node.ComputeMinMaxSize(WritingMode::kHorizontalTb, {});
+  auto size = node.ComputeMinMaxSize(
+      WritingMode::kHorizontalTb,
+      MinMaxSizeInput(/* percentage_resolution_block_size */ (LayoutUnit())));
   EXPECT_EQ(size.min_size, LayoutUnit(60));
   EXPECT_EQ(size.max_size, LayoutUnit(110));
 }
diff --git a/third_party/blink/renderer/core/layout/ng/layout_box_utils.cc b/third_party/blink/renderer/core/layout/ng/layout_box_utils.cc
new file mode 100644
index 0000000..c3fb03c
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/ng/layout_box_utils.cc
@@ -0,0 +1,63 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/layout_box_utils.h"
+
+#include "third_party/blink/renderer/core/layout/layout_block.h"
+#include "third_party/blink/renderer/core/layout/layout_box.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
+
+namespace blink {
+
+LayoutUnit LayoutBoxUtils::AvailableLogicalWidth(const LayoutBox& box,
+                                                 const LayoutBlock* cb) {
+  auto writing_mode = box.StyleRef().GetWritingMode();
+  bool parallel_containing_block = IsParallelWritingMode(
+      cb ? cb->StyleRef().GetWritingMode() : writing_mode, writing_mode);
+
+  // Grid layout sets OverrideContainingBlockContentLogicalWidth|Height
+  if (parallel_containing_block &&
+      box.HasOverrideContainingBlockContentLogicalWidth()) {
+    return box.OverrideContainingBlockContentLogicalWidth()
+        .ClampNegativeToZero();
+  }
+
+  if (!parallel_containing_block &&
+      box.HasOverrideContainingBlockContentLogicalHeight()) {
+    return box.OverrideContainingBlockContentLogicalHeight()
+        .ClampNegativeToZero();
+  }
+
+  if (parallel_containing_block)
+    return box.ContainingBlockLogicalWidthForContent().ClampNegativeToZero();
+
+  return box.PerpendicularContainingBlockLogicalHeight().ClampNegativeToZero();
+}
+
+LayoutUnit LayoutBoxUtils::AvailableLogicalHeight(const LayoutBox& box,
+                                                  const LayoutBlock* cb) {
+  auto writing_mode = box.StyleRef().GetWritingMode();
+  bool parallel_containing_block = IsParallelWritingMode(
+      cb ? cb->StyleRef().GetWritingMode() : writing_mode, writing_mode);
+
+  // Grid layout sets OverrideContainingBlockContentLogicalWidth|Height
+  if (parallel_containing_block &&
+      box.HasOverrideContainingBlockContentLogicalHeight())
+    return box.OverrideContainingBlockContentLogicalHeight();
+
+  if (!parallel_containing_block &&
+      box.HasOverrideContainingBlockContentLogicalWidth())
+    return box.OverrideContainingBlockContentLogicalWidth();
+
+  if (!box.Parent())
+    return box.View()->ViewLogicalHeightForPercentages();
+
+  DCHECK(cb);
+  if (parallel_containing_block)
+    return box.ContainingBlockLogicalHeightForPercentageResolution();
+
+  return box.ContainingBlockLogicalWidthForContent();
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/layout_box_utils.h b/third_party/blink/renderer/core/layout/ng/layout_box_utils.h
new file mode 100644
index 0000000..62eccf6
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/ng/layout_box_utils.h
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LAYOUT_BOX_UTILS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LAYOUT_BOX_UTILS_H_
+
+#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
+
+namespace blink {
+
+class LayoutBox;
+class LayoutBlock;
+
+// This static class should be used for querying information from a |LayoutBox|.
+class LayoutBoxUtils {
+  STATIC_ONLY(LayoutBoxUtils);
+
+ public:
+  // Returns the available logical width/height for |box| accounting for:
+  //  - Orthogonal writing modes.
+  //  - Any containing block override sizes set.
+  static LayoutUnit AvailableLogicalWidth(const LayoutBox& box,
+                                          const LayoutBlock* cb);
+  static LayoutUnit AvailableLogicalHeight(const LayoutBox& box,
+                                           const LayoutBlock* cb);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LAYOUT_BOX_UTILS_H_
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
index 07a20de2..b90c189 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/layout/hit_test_location.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/layout_box_utils.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
@@ -81,7 +82,10 @@
     Base::ComputeIntrinsicLogicalWidths(min_logical_width, max_logical_width);
     return;
   }
-  MinMaxSizeInput input;
+
+  LayoutUnit available_logical_height =
+      LayoutBoxUtils::AvailableLogicalHeight(*this, Base::ContainingBlock());
+  MinMaxSizeInput input(available_logical_height);
   // This function returns content-box plus scrollbar.
   input.size_type = NGMinMaxSizeType::kContentBoxSize;
   MinMaxSize sizes =
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index 14a70be..018d7c5 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -196,6 +196,11 @@
     return sizes;
   }
 
+  LayoutUnit child_percentage_resolution_block_size =
+      CalculateChildPercentageBlockSizeForMinMax(
+          ConstraintSpace(), Node(), border_padding,
+          input.percentage_resolution_block_size);
+
   const TextDirection direction = Style().Direction();
   LayoutUnit float_left_inline_size = input.float_left_inline_size;
   LayoutUnit float_right_inline_size = input.float_right_inline_size;
@@ -229,9 +234,11 @@
         float_right_inline_size = LayoutUnit();
     }
 
-    MinMaxSizeInput child_input;
-    if (child.IsInline() || child.IsAnonymousBlock())
-      child_input = {float_left_inline_size, float_right_inline_size};
+    MinMaxSizeInput child_input(child_percentage_resolution_block_size);
+    if (child.IsInline() || child.IsAnonymousBlock()) {
+      child_input.float_left_inline_size = float_left_inline_size;
+      child_input.float_right_inline_size = float_right_inline_size;
+    }
 
     MinMaxSize child_sizes;
     if (child.IsInline()) {
@@ -355,7 +362,9 @@
                                   ? NGBoxStrut()
                                   : border_padding_ + scrollbars;
   NGLogicalSize border_box_size = CalculateBorderBoxSize(
-      ConstraintSpace(), Node(), border_padding_, CalculateDefaultBlockSize());
+      ConstraintSpace(), Node(), border_padding_,
+      CalculateDefaultBlockSize(ConstraintSpace(), Node(),
+                                border_scrollbar_padding_));
 
   child_available_size_ =
       ShrinkAvailableSize(border_box_size, border_scrollbar_padding_);
@@ -2269,19 +2278,6 @@
   unpositioned_floats_.Shrink(0);
 }
 
-// In quirks mode, BODY and HTML elements must completely fill initial
-// containing block. Percentage resolution size is minimal size
-// that would fill the ICB.
-LayoutUnit NGBlockLayoutAlgorithm::CalculateDefaultBlockSize() {
-  if (Node().IsQuirkyAndFillsViewport()) {
-    LayoutUnit block_size = ConstraintSpace().AvailableSize().block_size;
-    block_size -= ComputeMarginsForSelf(ConstraintSpace(), Style()).BlockSum();
-    return std::max(block_size.ClampNegativeToZero(),
-                    border_scrollbar_padding_.BlockSum());
-  }
-  return NGSizeIndefinite;
-}
-
 LayoutUnit NGBlockLayoutAlgorithm::CalculateMinimumBlockSize(
     const NGMarginStrut& end_margin_strut) {
   if (!Node().GetDocument().InQuirksMode())
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
index dffc9cfe..160edc1 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
@@ -276,10 +276,6 @@
       LayoutUnit child_bfc_line_offset,
       const base::Optional<LayoutUnit>& child_bfc_block_offset);
 
-  // Computes default content size for HTML and BODY elements in quirks mode.
-  // Returns NGSizeIndefinite in all other cases.
-  LayoutUnit CalculateDefaultBlockSize();
-
   // Computes minimum size for HTML and BODY elements in quirks mode.
   // Returns NGSizeIndefinite in all other cases.
   LayoutUnit CalculateMinimumBlockSize(const NGMarginStrut& end_margin_strut);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
index b28fab50..2048191 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -50,7 +50,8 @@
         NGLogicalSize(LayoutUnit(), LayoutUnit()));
 
     NGBlockLayoutAlgorithm algorithm(node, space);
-    MinMaxSizeInput input;
+    MinMaxSizeInput input(
+        /* percentage_resolution_block_size */ (LayoutUnit()));
     auto min_max = algorithm.ComputeMinMaxSize(input);
     EXPECT_TRUE(min_max.has_value());
     return *min_max;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 8abf54f..32d6b73 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -362,7 +362,7 @@
   // if we're outside of layout, we can't do that. This can happen on Mac.
   if ((!CanUseNewLayout() && !is_orthogonal_flow_root) ||
       (is_orthogonal_flow_root && !box_->GetFrameView()->IsInPerformLayout())) {
-    return ComputeMinMaxSizeFromLegacy(input.size_type);
+    return ComputeMinMaxSizeFromLegacy(input);
   }
 
   NGConstraintSpace zero_constraint_space =
@@ -406,7 +406,7 @@
   if (!box_->GetFrameView()->IsInPerformLayout()) {
     // We can't synthesize these using Layout() if we're not in PerformLayout.
     // This situation can happen on mac. Fall back to legacy instead.
-    return ComputeMinMaxSizeFromLegacy(input.size_type);
+    return ComputeMinMaxSizeFromLegacy(input);
   }
 
   // Have to synthesize this value.
@@ -441,17 +441,28 @@
 }
 
 MinMaxSize NGBlockNode::ComputeMinMaxSizeFromLegacy(
-    NGMinMaxSizeType type) const {
+    const MinMaxSizeInput& input) const {
+  bool needs_size_reset = false;
+  if (!box_->HasOverrideContainingBlockContentLogicalHeight()) {
+    box_->SetOverrideContainingBlockContentLogicalHeight(
+        input.percentage_resolution_block_size);
+    needs_size_reset = true;
+  }
+
   MinMaxSize sizes;
   // ComputeIntrinsicLogicalWidths returns content-box + scrollbar.
   box_->ComputeIntrinsicLogicalWidths(sizes.min_size, sizes.max_size);
-  if (type == NGMinMaxSizeType::kContentBoxSize) {
+  if (input.size_type == NGMinMaxSizeType::kContentBoxSize) {
     sizes -= LayoutUnit(box_->ScrollbarLogicalWidth());
     DCHECK_GE(sizes.min_size, LayoutUnit());
     DCHECK_GE(sizes.max_size, LayoutUnit());
   } else {
     sizes += box_->BorderAndPaddingLogicalWidth();
   }
+
+  if (needs_size_reset)
+    box_->ClearOverrideContainingBlockContentSize();
+
   return sizes;
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.h b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
index c3035be70..66d9316 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
@@ -60,7 +60,7 @@
                                const MinMaxSizeInput&,
                                const NGConstraintSpace* = nullptr);
 
-  MinMaxSize ComputeMinMaxSizeFromLegacy(NGMinMaxSizeType) const;
+  MinMaxSize ComputeMinMaxSizeFromLegacy(const MinMaxSizeInput&) const;
 
   NGBoxStrut GetScrollbarSizes() const;
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc
index b623795..52327cf 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc
@@ -159,8 +159,9 @@
   const int kWidth = 30;
 
   NGBlockNode box(ToLayoutBox(GetLayoutObjectByElementId("box")));
-  MinMaxSize sizes =
-      box.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
+  MinMaxSize sizes = box.ComputeMinMaxSize(
+      WritingMode::kHorizontalTb,
+      MinMaxSizeInput(/* percentage_resolution_block_size */ LayoutUnit()));
   EXPECT_EQ(LayoutUnit(kWidth), sizes.min_size);
   EXPECT_EQ(LayoutUnit(kWidth), sizes.max_size);
 }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
index 37f15d7..d3964124 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
@@ -1988,7 +1988,8 @@
       NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
   NGColumnLayoutAlgorithm algorithm(node, space);
   base::Optional<MinMaxSize> size;
-  MinMaxSizeInput zero_input;
+  MinMaxSizeInput zero_input(
+      /* percentage_resolution_block_size */ (LayoutUnit()));
 
   // Both column-count and column-width set.
   style->SetColumnCount(3);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
index 8653c4b..daabe5f3 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/core/layout/layout_block.h"
 #include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/layout/ng/layout_box_utils.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
 
@@ -34,52 +35,18 @@
 
 NGConstraintSpace NGConstraintSpace::CreateFromLayoutObject(
     const LayoutBox& box) {
-  auto writing_mode = box.StyleRef().GetWritingMode();
-  bool parallel_containing_block = IsParallelWritingMode(
-      box.ContainingBlock()->StyleRef().GetWritingMode(), writing_mode);
-  bool fixed_inline = false, fixed_block = false;
-  bool fixed_block_is_definite = true;
+  const LayoutBlock* cb = box.ContainingBlock();
 
-  LayoutUnit available_logical_width;
-  if (parallel_containing_block &&
-      box.HasOverrideContainingBlockContentLogicalWidth()) {
-    // Grid layout sets OverrideContainingBlockContentLogicalWidth|Height
-    available_logical_width = box.OverrideContainingBlockContentLogicalWidth();
-  } else if (!parallel_containing_block &&
-             box.HasOverrideContainingBlockContentLogicalHeight()) {
-    available_logical_width = box.OverrideContainingBlockContentLogicalHeight();
-  } else {
-    if (parallel_containing_block)
-      available_logical_width = box.ContainingBlockLogicalWidthForContent();
-    else
-      available_logical_width = box.PerpendicularContainingBlockLogicalHeight();
-  }
-  available_logical_width = std::max(LayoutUnit(), available_logical_width);
-
-  LayoutUnit available_logical_height;
-  if (parallel_containing_block &&
-      box.HasOverrideContainingBlockContentLogicalHeight()) {
-    // Grid layout sets OverrideContainingBlockContentLogicalWidth|Height
-    available_logical_height =
-        box.OverrideContainingBlockContentLogicalHeight();
-  } else if (!parallel_containing_block &&
-             box.HasOverrideContainingBlockContentLogicalWidth()) {
-    available_logical_height = box.OverrideContainingBlockContentLogicalWidth();
-  } else {
-    if (!box.Parent()) {
-      available_logical_height = box.View()->ViewLogicalHeightForPercentages();
-    } else if (box.ContainingBlock()) {
-      if (parallel_containing_block) {
-        available_logical_height =
-            box.ContainingBlockLogicalHeightForPercentageResolution();
-      } else {
-        available_logical_height = box.ContainingBlockLogicalWidthForContent();
-      }
-    }
-  }
+  LayoutUnit available_logical_width =
+      LayoutBoxUtils::AvailableLogicalWidth(box, cb);
+  LayoutUnit available_logical_height =
+      LayoutBoxUtils::AvailableLogicalHeight(box, cb);
   NGLogicalSize percentage_size = {available_logical_width,
                                    available_logical_height};
   NGLogicalSize available_size = percentage_size;
+
+  bool fixed_inline = false, fixed_block = false;
+  bool fixed_block_is_definite = true;
   if (box.HasOverrideLogicalWidth()) {
     available_size.inline_size = box.OverrideLogicalWidth();
     fixed_inline = true;
@@ -107,6 +74,9 @@
   // DCHECK(is_new_fc,
   //  box.IsLayoutBlock() && ToLayoutBlock(box).CreatesNewFormattingContext());
 
+  auto writing_mode = box.StyleRef().GetWritingMode();
+  bool parallel_containing_block = IsParallelWritingMode(
+      cb ? cb->StyleRef().GetWritingMode() : writing_mode, writing_mode);
   NGConstraintSpaceBuilder builder(writing_mode, writing_mode, is_new_fc,
                                    !parallel_containing_block);
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
index a2b06d56..d289b395 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
@@ -53,7 +53,8 @@
         NGLogicalSize(LayoutUnit(), LayoutUnit()));
 
     NGFieldsetLayoutAlgorithm algorithm(node, space);
-    MinMaxSizeInput input;
+    MinMaxSizeInput input(
+        /* percentage_resolution_block_size */ (LayoutUnit()));
     auto min_max = algorithm.ComputeMinMaxSize(input);
     EXPECT_TRUE(min_max.has_value());
     return *min_max;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
index 987d020e..a7a9b511 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
@@ -96,9 +96,10 @@
 
     // We want the child's min/max size in its writing mode, not ours. We'll
     // only ever use it if the child's inline axis is our main axis.
-    MinMaxSizeInput zero_input;
+    MinMaxSizeInput input(
+        /* percentage_resolution_block_size */ content_box_size_.block_size);
     MinMaxSize min_max_sizes_border_box = child.ComputeMinMaxSize(
-        child_style.GetWritingMode(), zero_input, &child_space);
+        child_style.GetWritingMode(), input, &child_space);
     // TODO(dgrogan): Don't layout every time, just when you need to.
     scoped_refptr<NGLayoutResult> layout_result =
         child.Layout(child_space, nullptr /*break token*/);
@@ -351,19 +352,27 @@
     return sizes;
   }
 
+  LayoutUnit child_percentage_resolution_block_size =
+      CalculateChildPercentageBlockSizeForMinMax(
+          ConstraintSpace(), Node(), borders_ + padding_,
+          input.percentage_resolution_block_size);
+
+  // Use default MinMaxSizeInput:
+  //   - Children of flexbox ignore any specified float properties, so children
+  //     never have to take floated siblings into account, and external floats
+  //     don't make it through the new formatting context that flexbox
+  //     establishes.
+  //   - We want the child's border box MinMaxSize, which is the default.
+  MinMaxSizeInput child_input(child_percentage_resolution_block_size);
+
   for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child;
        generic_child = generic_child.NextSibling()) {
     NGBlockNode child = ToNGBlockNode(generic_child);
     if (child.IsOutOfFlowPositioned())
       continue;
-    // Use default MinMaxSizeInput:
-    //   - Children of flexbox ignore any specified float properties, so
-    //     children never have to take floated siblings into account, and
-    //     external floats don't make it through the new formatting context that
-    //     flexbox establishes.
-    //   - We want the child's border box MinMaxSize, which is the default.
+
     MinMaxSize child_min_max_sizes =
-        ComputeMinAndMaxContentContribution(Style(), child, MinMaxSizeInput());
+        ComputeMinAndMaxContentContribution(Style(), child, child_input);
     NGBoxStrut child_margins = ComputeMinMaxMargins(Style(), child);
     child_min_max_sizes += child_margins.InlineSum();
     if (is_column_) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
index 1c28ffa9..863c1c4 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -34,8 +34,21 @@
 // nodes within the same formatting context need to know which floats are beside
 // them.
 struct MinMaxSizeInput {
+  // The min-max size calculation (un-intuitively) requires a percentage
+  // resolution size!
+  // This occurs when a replaced element has an intrinsic size. E.g.
+  // <div style="float: left; height: 100px">
+  //   <img sr="intrinsic-ratio-1x1.png" style="height: 50%;" />
+  // </div>
+  // In the above example float ends up with a width of 50px.
+  //
+  // As we don't perform any tree walking, we need to pass the percentage
+  // resolution block-size for min/max down the min/max size calculation.
+  explicit MinMaxSizeInput(LayoutUnit percentage_resolution_block_size)
+      : percentage_resolution_block_size(percentage_resolution_block_size) {}
   LayoutUnit float_left_inline_size;
   LayoutUnit float_right_inline_size;
+  LayoutUnit percentage_resolution_block_size;
 
   // Whether to return the size as a content-box size or border-box size.
   NGMinMaxSizeType size_type = NGMinMaxSizeType::kBorderBoxSize;
@@ -83,6 +96,9 @@
   bool IsBody() const { return IsBlock() && box_->IsBody(); }
   bool IsDocumentElement() const { return box_->IsDocumentElement(); }
   bool IsFlexItem() const { return IsBlock() && box_->IsFlexItemIncludingNG(); }
+  bool IsFlexBox() const {
+    return IsBlock() && box_->IsFlexibleBoxIncludingNG();
+  }
   bool ShouldBeConsideredAsReplaced() const {
     return box_->ShouldBeConsideredAsReplaced();
   }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
index 8919c22..9899e56 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -192,13 +192,15 @@
   }
 }
 
-LayoutUnit ResolveBlockLength(const NGConstraintSpace& constraint_space,
-                              const ComputedStyle& style,
-                              const NGBoxStrut& border_padding,
-                              const Length& length,
-                              LayoutUnit content_size,
-                              LengthResolveType type,
-                              LengthResolvePhase phase) {
+LayoutUnit ResolveBlockLength(
+    const NGConstraintSpace& constraint_space,
+    const ComputedStyle& style,
+    const NGBoxStrut& border_padding,
+    const Length& length,
+    LayoutUnit content_size,
+    LengthResolveType type,
+    LengthResolvePhase phase,
+    const LayoutUnit* opt_percentage_resolution_block_size_for_min_max) {
   DCHECK_EQ(constraint_space.GetWritingMode(), style.GetWritingMode());
 
   if (constraint_space.IsAnonymous())
@@ -226,9 +228,12 @@
   // cannot resolve percentages / calc() / -webkit-fill-available.
   bool size_is_unresolvable = false;
   if (length.IsPercentOrCalc()) {
-    size_is_unresolvable =
-        phase == LengthResolvePhase::kIntrinsic ||
-        constraint_space.PercentageResolutionBlockSize() == NGSizeIndefinite;
+    LayoutUnit percentage_resolution_block_size =
+        opt_percentage_resolution_block_size_for_min_max
+            ? *opt_percentage_resolution_block_size_for_min_max
+            : constraint_space.PercentageResolutionBlockSize();
+    size_is_unresolvable = phase == LengthResolvePhase::kIntrinsic ||
+                           percentage_resolution_block_size == NGSizeIndefinite;
   } else if (length.IsFillAvailable()) {
     size_is_unresolvable =
         phase == LengthResolvePhase::kIntrinsic ||
@@ -258,9 +263,12 @@
     case kPercent:
     case kFixed:
     case kCalculated: {
-      LayoutUnit percentage_resolution_size =
-          constraint_space.PercentageResolutionBlockSize();
-      LayoutUnit value = ValueForLength(length, percentage_resolution_size);
+      LayoutUnit percentage_resolution_block_size =
+          opt_percentage_resolution_block_size_for_min_max
+              ? *opt_percentage_resolution_block_size_for_min_max
+              : constraint_space.PercentageResolutionBlockSize();
+      LayoutUnit value =
+          ValueForLength(length, percentage_resolution_block_size);
 
       // Percentage-sized children of table cells, in the table "layout" phase,
       // pretend they have box-sizing: border-box.
@@ -504,8 +512,9 @@
     if (override_minmax_for_test) {
       min_and_max = *override_minmax_for_test;
     } else {
-      min_and_max = node.ComputeMinMaxSize(space.GetWritingMode(),
-                                           MinMaxSizeInput(), &space);
+      min_and_max = node.ComputeMinMaxSize(
+          space.GetWritingMode(),
+          MinMaxSizeInput(space.PercentageResolutionBlockSize()), &space);
       // Cache these computed values
       MinMaxSize contribution = ComputeMinAndMaxContentContribution(
           style.GetWritingMode(), style, border_padding, min_and_max);
@@ -533,11 +542,14 @@
     const NGConstraintSpace& constraint_space,
     const ComputedStyle& style,
     const NGBoxStrut& border_padding,
-    LayoutUnit content_size) {
+    LayoutUnit content_size,
+    const LayoutUnit* opt_percentage_resolution_block_size_for_min_max =
+        nullptr) {
   LayoutUnit extent = ResolveBlockLength(
       constraint_space, style, border_padding, style.LogicalHeight(),
       content_size, LengthResolveType::kContentSize,
-      LengthResolvePhase::kLayout);
+      LengthResolvePhase::kLayout,
+      opt_percentage_resolution_block_size_for_min_max);
   if (extent == NGSizeIndefinite) {
     DCHECK_EQ(content_size, NGSizeIndefinite);
     return extent;
@@ -545,10 +557,12 @@
 
   LayoutUnit max = ResolveBlockLength(
       constraint_space, style, border_padding, style.LogicalMaxHeight(),
-      content_size, LengthResolveType::kMaxSize, LengthResolvePhase::kLayout);
+      content_size, LengthResolveType::kMaxSize, LengthResolvePhase::kLayout,
+      opt_percentage_resolution_block_size_for_min_max);
   LayoutUnit min = ResolveBlockLength(
       constraint_space, style, border_padding, style.LogicalMinHeight(),
-      content_size, LengthResolveType::kMinSize, LengthResolvePhase::kLayout);
+      content_size, LengthResolveType::kMinSize, LengthResolvePhase::kLayout,
+      opt_percentage_resolution_block_size_for_min_max);
 
   return ConstrainByMinMax(extent, min, max);
 }
@@ -1135,6 +1149,21 @@
   return size;
 }
 
+LayoutUnit CalculateDefaultBlockSize(
+    const NGConstraintSpace& space,
+    const NGBlockNode& node,
+    const NGBoxStrut& border_scrollbar_padding) {
+  // In quirks mode, html and body elements will completely fill the ICB, block
+  // percentages should resolve against this size.
+  if (node.IsQuirkyAndFillsViewport()) {
+    LayoutUnit block_size = space.AvailableSize().block_size;
+    block_size -= ComputeMarginsForSelf(space, node.Style()).BlockSum();
+    return std::max(block_size.ClampNegativeToZero(),
+                    border_scrollbar_padding.BlockSum());
+  }
+  return NGSizeIndefinite;
+}
+
 namespace {
 
 // Implements the common part of the child percentage size calculation. Deals
@@ -1155,9 +1184,11 @@
   // In quirks mode the percentage resolution height is passed from parent to
   // child.
   // https://quirks.spec.whatwg.org/#the-percentage-height-calculation-quirk
+  // TODO(layout-dev): grid, and css-layout-api containers need to also bypass
+  // this quirk.
   if (child_percentage_size.block_size == NGSizeIndefinite &&
       node.GetDocument().InQuirksMode() && !node.Style().IsDisplayTableType() &&
-      !node.Style().HasOutOfFlowPosition()) {
+      !node.Style().HasOutOfFlowPosition() && !node.IsFlexBox()) {
     child_percentage_size.block_size = parent_percentage_block_size;
   }
 
@@ -1233,4 +1264,33 @@
       space.ReplacedPercentageResolutionBlockSize());
 }
 
+LayoutUnit CalculateChildPercentageBlockSizeForMinMax(
+    const NGConstraintSpace& space,
+    const NGBlockNode node,
+    const NGBoxStrut& border_padding,
+    LayoutUnit parent_percentage_block_size) {
+  // Anonymous block or spaces should pass the percent size straight through.
+  if (space.IsAnonymous() || node.IsAnonymousBlock())
+    return parent_percentage_block_size;
+
+  LayoutUnit block_size = ComputeBlockSizeForFragmentInternal(
+      space, node.Style(), border_padding,
+      CalculateDefaultBlockSize(space, node, border_padding),
+      &parent_percentage_block_size);
+
+  LayoutUnit child_percentage_block_size =
+      block_size == NGSizeIndefinite
+          ? NGSizeIndefinite
+          : (block_size - border_padding.BlockSum()).ClampNegativeToZero();
+
+  // TODO(layout-dev): grid, and css-layout-api containers need to also bypass
+  // this quirk.
+  if (child_percentage_block_size == NGSizeIndefinite &&
+      node.GetDocument().InQuirksMode() &&
+      !node.Style().HasOutOfFlowPosition() && !node.IsFlexBox())
+    child_percentage_block_size = parent_percentage_block_size;
+
+  return child_percentage_block_size;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
index 256d64cf..53daf49 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
@@ -66,8 +66,12 @@
 
 // Resolve means translate a Length to a LayoutUnit, using parent info
 // (represented by ConstraintSpace) as necessary for things like percents.
-//
-// MinMaxSize is used only when the length is intrinsic (fit-content, etc).
+//  - |MinMaxSize| is only used when the length is intrinsic (fit-content, etc).
+//  - |Length| is the length to resolve.
+//  - |LengthResolveType| is the type of length function, based on its CSS
+//    property (see definition above).
+//  - |LengthResolveType| indicates what type of layout pass we are within (see
+//    definition above).
 CORE_EXPORT LayoutUnit ResolveInlineLength(const NGConstraintSpace&,
                                            const ComputedStyle&,
                                            const NGBoxStrut& border_padding,
@@ -76,15 +80,18 @@
                                            LengthResolveType,
                                            LengthResolvePhase);
 
-// Same as ResolveInlineLength, except here content_size roughly plays the part
-// of MinMaxSize.
-CORE_EXPORT LayoutUnit ResolveBlockLength(const NGConstraintSpace&,
-                                          const ComputedStyle&,
-                                          const NGBoxStrut& border_padding,
-                                          const Length&,
-                                          LayoutUnit content_size,
-                                          LengthResolveType,
-                                          LengthResolvePhase);
+// Same as ResolveInlineLength, except here |content_size| roughly plays the
+// part of |MinMaxSize|.
+CORE_EXPORT LayoutUnit ResolveBlockLength(
+    const NGConstraintSpace&,
+    const ComputedStyle&,
+    const NGBoxStrut& border_padding,
+    const Length&,
+    LayoutUnit content_size,
+    LengthResolveType,
+    LengthResolvePhase,
+    const LayoutUnit* opt_percentage_resolution_block_size_for_min_max =
+        nullptr);
 
 // Convert margin/border/padding length to a layout unit using the
 // given constraint space.
@@ -341,6 +348,13 @@
 // allowed, in which case the inset will be ignored for block size.
 NGLogicalSize ShrinkAvailableSize(NGLogicalSize size, const NGBoxStrut& inset);
 
+// Calculates default content size for html and body elements in quirks mode.
+// Returns NGSizeIndefinite in all other cases.
+LayoutUnit CalculateDefaultBlockSize(
+    const NGConstraintSpace&,
+    const NGBlockNode&,
+    const NGBoxStrut& border_scrollbar_padding);
+
 // Calculates the percentage resolution size that children of the node should
 // use.
 NGLogicalSize CalculateChildPercentageSize(
@@ -357,6 +371,12 @@
     const NGBoxStrut& border_scrollbar_padding,
     const NGBoxStrut& border_padding);
 
+LayoutUnit CalculateChildPercentageBlockSizeForMinMax(
+    const NGConstraintSpace& constraint_space,
+    const NGBlockNode node,
+    const NGBoxStrut& border_padding,
+    LayoutUnit parent_percentage_block_size);
+
 }  // namespace blink
 
 #endif  // NGLengthUtils_h
diff --git a/third_party/blink/renderer/core/layout/ng/ng_link.h b/third_party/blink/renderer/core/layout/ng/ng_link.h
index 089992d..a67a3261 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_link.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_link.h
@@ -68,6 +68,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGLink);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGLink)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_LINK_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
index 1ec8f03..b0c973a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -377,8 +377,8 @@
       descendant.node.ShouldBeConsideredAsReplaced()) {
     // This is a new formatting context, so whatever happened on the outside
     // doesn't concern us.
-    MinMaxSizeInput zero_input;
-    min_max_size = node.ComputeMinMaxSize(descendant_writing_mode, zero_input,
+    MinMaxSizeInput input(container_content_size.block_size);
+    min_max_size = node.ComputeMinMaxSize(descendant_writing_mode, input,
                                           &descendant_constraint_space);
   }
 
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h b/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h
index e04ba158..3b879096 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h
+++ b/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h
@@ -82,6 +82,6 @@
 }  // namespace blink
 
 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(
-    blink::SVGTextLayoutAttributesBuilder::TextPosition);
+    blink::SVGTextLayoutAttributesBuilder::TextPosition)
 
 #endif
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache.h b/third_party/blink/renderer/core/loader/appcache/application_cache.h
index 855c5af..f567bf83 100644
--- a/third_party/blink/renderer/core/loader/appcache/application_cache.h
+++ b/third_party/blink/renderer/core/loader/appcache/application_cache.h
@@ -58,14 +58,14 @@
 
   // Explicitly named attribute event listener helpers
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(checking, kChecking);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(noupdate, kNoupdate);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(downloading, kDownloading);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(updateready, kUpdateready);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(cached, kCached);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(obsolete, kObsolete);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(checking, kChecking)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(noupdate, kNoupdate)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(downloading, kDownloading)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(updateready, kUpdateready)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(cached, kCached)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(obsolete, kObsolete)
 
   const AtomicString& InterfaceName() const override;
   ExecutionContext* GetExecutionContext() const override;
diff --git a/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h b/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h
index b4459470..689bf12 100644
--- a/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h
+++ b/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h
@@ -49,7 +49,7 @@
   void start(ExceptionState&);
   void stop();
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(interfacerequest, kInterfacerequest);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(interfacerequest, kInterfacerequest)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index 0157616..f26b329 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -51,6 +51,7 @@
 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/inspector/console_message_storage.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
 #include "third_party/blink/renderer/core/layout/text_autosizer.h"
 #include "third_party/blink/renderer/core/page/autoscroll_controller.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
@@ -664,6 +665,15 @@
       }
       break;
     }
+    case SettingsDelegate::kPaintChange:
+      for (Frame* frame = MainFrame(); frame;
+           frame = frame->Tree().TraverseNext()) {
+        if (!frame->IsLocalFrame())
+          continue;
+        if (LayoutView* view = ToLocalFrame(frame)->ContentLayoutObject())
+          view->InvalidatePaintForViewAndCompositedLayers();
+      }
+      break;
   }
 }
 
diff --git a/third_party/blink/renderer/core/paint/image_painter.cc b/third_party/blink/renderer/core/paint/image_painter.cc
index 4b59ec8..dc7b8db 100644
--- a/third_party/blink/renderer/core/paint/image_painter.cc
+++ b/third_party/blink/renderer/core/paint/image_painter.cc
@@ -199,6 +199,9 @@
     placeholder_image->SetIconAndTextScaleFactor(
         layout_image_.GetFrame()->PageZoomFactor());
     image = std::move(placeholder_image);
+
+    // Report layout related image policy violation.
+    layout_image_.ReportImagePolicyViolation();
   }
 
   context.DrawImage(
diff --git a/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc b/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc
index d766d5c70..9b3ee11 100644
--- a/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc
+++ b/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc
@@ -14,7 +14,7 @@
 using Behavior = WebScrollIntoViewParams::Behavior;
 
 // Make sure we keep the public enums in sync with the internal ones.
-ASSERT_SIZE(AlignmentBehavior, ScrollAlignmentBehavior)
+ASSERT_SIZE(AlignmentBehavior, ScrollAlignmentBehavior);
 STATIC_ASSERT_ENUM(AlignmentBehavior::kNoScroll,
                    ScrollAlignmentBehavior::kScrollAlignmentNoScroll);
 STATIC_ASSERT_ENUM(AlignmentBehavior::kCenter,
@@ -30,14 +30,14 @@
 STATIC_ASSERT_ENUM(AlignmentBehavior::kClosestEdge,
                    ScrollAlignmentBehavior::kScrollAlignmentClosestEdge);
 
-ASSERT_SIZE(Type, ScrollType)
+ASSERT_SIZE(Type, ScrollType);
 STATIC_ASSERT_ENUM(Type::kUser, ScrollType::kUserScroll);
 STATIC_ASSERT_ENUM(Type::kProgrammatic, ScrollType::kProgrammaticScroll);
 STATIC_ASSERT_ENUM(Type::kClamping, ScrollType::kClampingScroll);
 STATIC_ASSERT_ENUM(Type::kAnchoring, ScrollType::kAnchoringScroll);
 STATIC_ASSERT_ENUM(Type::kSequenced, ScrollType::kSequencedScroll);
 
-ASSERT_SIZE(Behavior, ScrollBehavior)
+ASSERT_SIZE(Behavior, ScrollBehavior);
 STATIC_ASSERT_ENUM(Behavior::kAuto, ScrollBehavior::kScrollBehaviorAuto);
 STATIC_ASSERT_ENUM(Behavior::kInstant, ScrollBehavior::kScrollBehaviorInstant);
 STATIC_ASSERT_ENUM(Behavior::kSmooth, ScrollBehavior::kScrollBehaviorSmooth);
diff --git a/third_party/blink/renderer/core/style/cursor_data.h b/third_party/blink/renderer/core/style/cursor_data.h
index 157170a..6556ff5b 100644
--- a/third_party/blink/renderer/core/style/cursor_data.h
+++ b/third_party/blink/renderer/core/style/cursor_data.h
@@ -66,6 +66,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::CursorData);
+WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::CursorData)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_CURSOR_DATA_H_
diff --git a/third_party/blink/renderer/core/style/filter_operation.h b/third_party/blink/renderer/core/style/filter_operation.h
index 568aeb48..2d8ae00 100644
--- a/third_party/blink/renderer/core/style/filter_operation.h
+++ b/third_party/blink/renderer/core/style/filter_operation.h
@@ -126,7 +126,7 @@
 #define DEFINE_FILTER_OPERATION_TYPE_CASTS(thisType, operationType)  \
   DEFINE_TYPE_CASTS(thisType, FilterOperation, op,                   \
                     op->GetType() == FilterOperation::operationType, \
-                    op.GetType() == FilterOperation::operationType);
+                    op.GetType() == FilterOperation::operationType)
 
 class CORE_EXPORT ReferenceFilterOperation : public FilterOperation {
  public:
@@ -343,6 +343,8 @@
 };
 DEFINE_FILTER_OPERATION_TYPE_CASTS(BoxReflectFilterOperation, BOX_REFLECT);
 
+#undef DEFINE_FILTER_OPERATION_TYPE_CASTS
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_FILTER_OPERATION_H_
diff --git a/third_party/blink/renderer/core/svg/properties/svg_property.h b/third_party/blink/renderer/core/svg/properties/svg_property.h
index a9fd0864..516ed39 100644
--- a/third_party/blink/renderer/core/svg/properties/svg_property.h
+++ b/third_party/blink/renderer/core/svg/properties/svg_property.h
@@ -102,7 +102,7 @@
 #define DEFINE_SVG_PROPERTY_TYPE_CASTS(thisType)               \
   DEFINE_TYPE_CASTS(thisType, SVGPropertyBase, value,          \
                     value->GetType() == thisType::ClassType(), \
-                    value.GetType() == thisType::ClassType());
+                    value.GetType() == thisType::ClassType())
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/svg/svg_animation_element.h b/third_party/blink/renderer/core/svg/svg_animation_element.h
index 9c03ef7..3b546c0 100644
--- a/third_party/blink/renderer/core/svg/svg_animation_element.h
+++ b/third_party/blink/renderer/core/svg/svg_animation_element.h
@@ -65,9 +65,9 @@
   void endElement() { endElementAt(0); }
   void endElementAt(float offset);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(begin, kBeginEvent);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEndEvent);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(repeat, kRepeatEvent);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(begin, kBeginEvent)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEndEvent)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(repeat, kRepeatEvent)
 
   virtual bool IsAdditive();
   bool IsAccumulated() const;
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 13a57666..a4b7c35 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -36,7 +36,6 @@
 #include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_availability.h"
 #include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_client.h"
 #include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_connection_type.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
@@ -3236,73 +3235,6 @@
       .GetInterestedElement();
 }
 
-void Internals::setNetworkConnectionInfoOverride(
-    bool on_line,
-    const String& type,
-    const String& effective_type,
-    unsigned long http_rtt_msec,
-    double downlink_max_mbps,
-    ExceptionState& exception_state) {
-  WebConnectionType webtype;
-  if (type == "cellular2g") {
-    webtype = kWebConnectionTypeCellular2G;
-  } else if (type == "cellular3g") {
-    webtype = kWebConnectionTypeCellular3G;
-  } else if (type == "cellular4g") {
-    webtype = kWebConnectionTypeCellular4G;
-  } else if (type == "bluetooth") {
-    webtype = kWebConnectionTypeBluetooth;
-  } else if (type == "ethernet") {
-    webtype = kWebConnectionTypeEthernet;
-  } else if (type == "wifi") {
-    webtype = kWebConnectionTypeWifi;
-  } else if (type == "wimax") {
-    webtype = kWebConnectionTypeWimax;
-  } else if (type == "other") {
-    webtype = kWebConnectionTypeOther;
-  } else if (type == "none") {
-    webtype = kWebConnectionTypeNone;
-  } else if (type == "unknown") {
-    webtype = kWebConnectionTypeUnknown;
-  } else {
-    exception_state.ThrowDOMException(
-        DOMExceptionCode::kNotFoundError,
-        ExceptionMessages::FailedToEnumerate("connection type", type));
-    return;
-  }
-  WebEffectiveConnectionType web_effective_type =
-      WebEffectiveConnectionType::kTypeUnknown;
-  if (effective_type == "offline") {
-    web_effective_type = WebEffectiveConnectionType::kTypeOffline;
-  } else if (effective_type == "slow-2g") {
-    web_effective_type = WebEffectiveConnectionType::kTypeSlow2G;
-  } else if (effective_type == "2g") {
-    web_effective_type = WebEffectiveConnectionType::kType2G;
-  } else if (effective_type == "3g") {
-    web_effective_type = WebEffectiveConnectionType::kType3G;
-  } else if (effective_type == "4g") {
-    web_effective_type = WebEffectiveConnectionType::kType4G;
-  } else if (effective_type != "unknown") {
-    exception_state.ThrowDOMException(
-        DOMExceptionCode::kNotFoundError,
-        ExceptionMessages::FailedToEnumerate("effective connection type",
-                                             effective_type));
-    return;
-  }
-  GetNetworkStateNotifier().SetNetworkConnectionInfoOverride(
-      on_line, webtype, web_effective_type, http_rtt_msec, downlink_max_mbps);
-  GetFrame()->Client()->SetEffectiveConnectionTypeForTesting(
-      web_effective_type);
-}
-
-void Internals::setSaveDataEnabled(bool enabled) {
-  GetNetworkStateNotifier().SetSaveDataEnabledOverride(enabled);
-}
-
-void Internals::clearNetworkConnectionInfoOverride() {
-  GetNetworkStateNotifier().ClearOverride();
-}
-
 unsigned Internals::countHitRegions(CanvasRenderingContext* context) {
   return context->HitRegionsCount();
 }
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h
index 5d0b826..4c10f910 100644
--- a/third_party/blink/renderer/core/testing/internals.h
+++ b/third_party/blink/renderer/core/testing/internals.h
@@ -497,16 +497,6 @@
 
   Element* interestedElement();
 
-  void setNetworkConnectionInfoOverride(bool,
-                                        const String&,
-                                        const String&,
-                                        unsigned long http_rtt_msec,
-                                        double downlink_max_mbps,
-                                        ExceptionState&);
-  void setSaveDataEnabled(bool);
-
-  void clearNetworkConnectionInfoOverride();
-
   unsigned countHitRegions(CanvasRenderingContext*);
 
   bool isInCanvasFontCache(Document*, const String&);
@@ -602,9 +592,10 @@
 
   void addEmbedderCustomElementName(const AtomicString& name, ExceptionState&);
 
+  LocalFrame* GetFrame() const;
+
  private:
   Document* ContextDocument() const;
-  LocalFrame* GetFrame() const;
   Vector<String> IconURLs(Document*, int icon_types_mask) const;
   DOMRectList* AnnotatedRegions(Document*, bool draggable, ExceptionState&);
   void HitTestRect(HitTestLocation&,
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl
index 20f0c67..87f51ee9 100644
--- a/third_party/blink/renderer/core/testing/internals.idl
+++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -24,13 +24,6 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-enum EffectiveConnectionType {
-    "slow-2g",
-    "2g",
-    "3g",
-    "4g"
-};
-
 [
     DoNotCheckConstants
 ] interface Internals {
@@ -331,11 +324,6 @@
     // attribute returns the currently interested element on the page.
     readonly attribute Element? interestedElement;
 
-    // These functions are for testing NetInfo. You must call clearNetworkConnectionInfoOverride() at the end.
-    [RaisesException] void setNetworkConnectionInfoOverride(boolean onLine, DOMString type, EffectiveConnectionType effective_type, unsigned long http_rtt_msec, double downlink_max_mbps);
-    void setSaveDataEnabled(boolean enabled);
-    void clearNetworkConnectionInfoOverride();
-
     // This function is for testing HitRegions on Canvas2D.
     unsigned long countHitRegions(CanvasRenderingContext2D context);
 
diff --git a/third_party/blink/renderer/core/timing/performance.h b/third_party/blink/renderer/core/timing/performance.h
index 67a78e8..61d06496 100644
--- a/third_party/blink/renderer/core/timing/performance.h
+++ b/third_party/blink/renderer/core/timing/performance.h
@@ -124,7 +124,7 @@
   void setResourceTimingBufferSize(unsigned);
 
   DEFINE_ATTRIBUTE_EVENT_LISTENER(resourcetimingbufferfull,
-                                  kResourcetimingbufferfull);
+                                  kResourcetimingbufferfull)
 
   void AddLongTaskTiming(
       TimeTicks start_time,
@@ -163,15 +163,14 @@
   void clearElementTimings();
   void setElementTimingBufferMaxSize(unsigned);
   DEFINE_ATTRIBUTE_EVENT_LISTENER(elementtimingbufferfull,
-                                  kElementtimingbufferfull);
+                                  kElementtimingbufferfull)
 
   bool IsEventTimingBufferFull() const;
   void AddEventTimingBuffer(PerformanceEventTiming&);
   unsigned EventTimingBufferSize() const;
   void clearEventTimings();
   void setEventTimingBufferMaxSize(unsigned);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(eventtimingbufferfull,
-                                  kEventtimingbufferfull);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(eventtimingbufferfull, kEventtimingbufferfull)
 
   void AddLayoutJankBuffer(PerformanceLayoutJank&);
 
diff --git a/third_party/blink/renderer/core/workers/abstract_worker.h b/third_party/blink/renderer/core/workers/abstract_worker.h
index 4002d52..12316ad 100644
--- a/third_party/blink/renderer/core/workers/abstract_worker.h
+++ b/third_party/blink/renderer/core/workers/abstract_worker.h
@@ -57,7 +57,7 @@
     return ContextLifecycleObserver::GetExecutionContext();
   }
 
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error, kError);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error, kError)
 
   AbstractWorker(ExecutionContext*);
   ~AbstractWorker() override;
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.h b/third_party/blink/renderer/core/workers/dedicated_worker.h
index 4faf98a..e4336bd 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker.h
+++ b/third_party/blink/renderer/core/workers/dedicated_worker.h
@@ -93,7 +93,7 @@
   // Returns the name specified by WorkerOptions.
   const String Name() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
index 4b36b39..c4b8cc1a 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
@@ -78,8 +78,8 @@
                    const PostMessageOptions*,
                    ExceptionState&);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
index 4f37a3d..7b779529 100644
--- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
@@ -64,7 +64,7 @@
       network::mojom::FetchCredentialsMode) override;
 
   // Setters/Getters for attributes in SharedWorkerGlobalScope.idl
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
   String name() const { return name_; }
 
   void Connect(MessagePortChannel channel);
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h
index 92c77ed..910ff018 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -103,10 +103,10 @@
 
   String origin() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(languagechange, kLanguagechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(rejectionhandled, kRejectionhandled);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(unhandledrejection, kUnhandledrejection);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(languagechange, kLanguagechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(rejectionhandled, kRejectionhandled)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(unhandledrejection, kUnhandledrejection)
 
   // WorkerUtils
   virtual void importScripts(const HeapVector<StringOrTrustedScriptURL>& urls,
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
index a7a66c838..9922e85c 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
@@ -164,7 +164,7 @@
   XMLHttpRequestUpload* upload();
   bool IsAsync() { return async_; }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange)
 
   void Trace(blink::Visitor*) override;
   const char* NameInHeapSnapshot() const override { return "XMLHttpRequest"; }
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.h b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.h
index 94e90770..581d1164 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.h
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.h
@@ -40,13 +40,13 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(load, kLoad);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend, kLoadend);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart, kLoadstart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(timeout, kTimeout);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(load, kLoad)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend, kLoadend)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart, kLoadstart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(timeout, kTimeout)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn
index da0819b..e0f82de 100644
--- a/third_party/blink/renderer/modules/BUILD.gn
+++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -183,6 +183,8 @@
     "accessibility/testing/internals_accessibility.h",
     "mediastream/testing/internals_media_stream.cc",
     "mediastream/testing/internals_media_stream.h",
+    "netinfo/testing/internals_net_info.cc",
+    "netinfo/testing/internals_net_info.h",
     "peerconnection/adapters/test/mock_ice_transport_adapter.h",
     "peerconnection/adapters/test/mock_ice_transport_adapter_cross_thread_factory.h",
     "peerconnection/adapters/test/mock_p2p_quic_packet_transport.h",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index 7d11bb3..3964f5e2 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -161,9 +161,9 @@
 
 }  // namespace blink
 
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::IgnoredReason);
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::NameSource);
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::DescriptionSource);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::IgnoredReason)
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::NameSource)
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::DescriptionSource)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/app_banner/dom_window_installation.h b/third_party/blink/renderer/modules/app_banner/dom_window_installation.h
index 8284875..8ed0c05 100644
--- a/third_party/blink/renderer/modules/app_banner/dom_window_installation.h
+++ b/third_party/blink/renderer/modules/app_banner/dom_window_installation.h
@@ -12,9 +12,9 @@
 
 class DOMWindowInstallation {
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(appinstalled, kAppinstalled);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(appinstalled, kAppinstalled)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(beforeinstallprompt,
-                                         kBeforeinstallprompt);
+                                         kBeforeinstallprompt)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
index 0f45142..4bf4c9e 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
@@ -95,7 +95,7 @@
 
   const String& unique_id() const { return unique_id_; }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress)
 
   ScriptPromise abort(ScriptState* script_state);
 
diff --git a/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h b/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h
index b1b4b6e..a5b970d 100644
--- a/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h
+++ b/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h
@@ -15,13 +15,13 @@
 
  public:
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetchsuccess,
-                                         kBackgroundfetchsuccess);
+                                         kBackgroundfetchsuccess)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetchfail,
-                                         kBackgroundfetchfail);
+                                         kBackgroundfetchfail)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetchabort,
-                                         kBackgroundfetchabort);
+                                         kBackgroundfetchabort)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetchclick,
-                                         kBackgroundfetchclick);
+                                         kBackgroundfetchclick)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/background_sync/service_worker_global_scope_sync.h b/third_party/blink/renderer/modules/background_sync/service_worker_global_scope_sync.h
index be2c50f..73d84c2 100644
--- a/third_party/blink/renderer/modules/background_sync/service_worker_global_scope_sync.h
+++ b/third_party/blink/renderer/modules/background_sync/service_worker_global_scope_sync.h
@@ -11,7 +11,7 @@
 
 class ServiceWorkerGlobalScopeSync {
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(sync, kSync);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(sync, kSync)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/battery/battery_manager.h b/third_party/blink/renderer/modules/battery/battery_manager.h
index fbed854..66cb8faf 100644
--- a/third_party/blink/renderer/modules/battery/battery_manager.h
+++ b/third_party/blink/renderer/modules/battery/battery_manager.h
@@ -45,11 +45,10 @@
   double dischargingTime();
   double level();
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(chargingchange, kChargingchange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(chargingtimechange, kChargingtimechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(dischargingtimechange,
-                                  kDischargingtimechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(levelchange, kLevelchange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(chargingchange, kChargingchange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(chargingtimechange, kChargingtimechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(dischargingtimechange, kDischargingtimechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(levelchange, kLevelchange)
 
   // Inherited from PlatformEventController.
   void DidUpdateData() override;
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.h b/third_party/blink/renderer/modules/bluetooth/bluetooth.h
index 725f016..35ccc4942 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.h
@@ -57,8 +57,7 @@
   // ContextLifecycleObserver interface.
   void ContextDestroyed(ExecutionContext*) override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived,
-                                  kAdvertisementreceived);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, kAdvertisementreceived)
 
   void CancelScan(mojo::BindingId);
 
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
index 91aa984..643215a7 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
@@ -84,7 +84,7 @@
   BluetoothRemoteGATTServer* gatt() { return gatt_; }
 
   DEFINE_ATTRIBUTE_EVENT_LISTENER(gattserverdisconnected,
-                                  kGattserverdisconnected);
+                                  kGattserverdisconnected)
 
  protected:
   // EventTarget overrides:
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
index 58f19445..16a11bf 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
@@ -98,7 +98,7 @@
   ScriptPromise stopNotifications(ScriptState*);
 
   DEFINE_ATTRIBUTE_EVENT_LISTENER(characteristicvaluechanged,
-                                  kCharacteristicvaluechanged);
+                                  kCharacteristicvaluechanged)
 
  protected:
   // EventTarget overrides.
diff --git a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
index eed58ca..38ccc7d 100644
--- a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
+++ b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
@@ -38,8 +38,8 @@
   String name() const { return name_; }
   void postMessage(const ScriptValue&, ExceptionState&);
   void close();
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror)
 
   // EventTarget:
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.h b/third_party/blink/renderer/modules/cookie_store/cookie_store.h
index ce75093a..84a15a954 100644
--- a/third_party/blink/renderer/modules/cookie_store/cookie_store.h
+++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.h
@@ -85,7 +85,7 @@
   void ContextDestroyed(ExecutionContext*) override;
 
   // EventTargetWithInlineData
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
   const AtomicString& InterfaceName() const override;
   ExecutionContext* GetExecutionContext() const override;
   void RemoveAllEventListeners() override;
diff --git a/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.h b/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.h
index 1c44f1b..3b8c598 100644
--- a/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.h
+++ b/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.h
@@ -20,7 +20,7 @@
  public:
   static CookieStore* cookieStore(ServiceWorkerGlobalScope&);
 
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cookiechange, kCookiechange);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cookiechange, kCookiechange)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/device_orientation/dom_window_device_motion.h b/third_party/blink/renderer/modules/device_orientation/dom_window_device_motion.h
index 84f657b..0df7283 100644
--- a/third_party/blink/renderer/modules/device_orientation/dom_window_device_motion.h
+++ b/third_party/blink/renderer/modules/device_orientation/dom_window_device_motion.h
@@ -11,7 +11,7 @@
 
 class DOMWindowDeviceMotion {
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(devicemotion, kDevicemotion);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(devicemotion, kDevicemotion)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/device_orientation/dom_window_device_orientation.h b/third_party/blink/renderer/modules/device_orientation/dom_window_device_orientation.h
index 8273c29..a3430ff 100644
--- a/third_party/blink/renderer/modules/device_orientation/dom_window_device_orientation.h
+++ b/third_party/blink/renderer/modules/device_orientation/dom_window_device_orientation.h
@@ -11,9 +11,9 @@
 
 class DOMWindowDeviceOrientation {
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(deviceorientation, kDeviceorientation);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(deviceorientation, kDeviceorientation)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(deviceorientationabsolute,
-                                         kDeviceorientationabsolute);
+                                         kDeviceorientationabsolute)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h b/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h
index 0da6cb1..e8a3452 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h
+++ b/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h
@@ -36,8 +36,8 @@
   static ScriptPromise setMediaKeys(ScriptState*,
                                     HTMLMediaElement&,
                                     MediaKeys*);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(encrypted, kEncrypted);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waitingforkey, kWaitingforkey);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(encrypted, kEncrypted)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waitingforkey, kWaitingforkey)
 
   // WebMediaPlayerEncryptedMediaClient methods
   void Encrypted(WebEncryptedMediaInitDataType,
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h
index 737756de..20ea68a 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h
+++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h
@@ -82,8 +82,8 @@
   double expiration() const { return expiration_; }
   ScriptPromise closed(ScriptState*);
   MediaKeyStatusMap* keyStatuses();
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(keystatuseschange, kKeystatuseschange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(keystatuseschange, kKeystatuseschange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
 
   ScriptPromise generateRequest(ScriptState*,
                                 const String& init_data_type,
diff --git a/third_party/blink/renderer/modules/eventsource/event_source.h b/third_party/blink/renderer/modules/eventsource/event_source.h
index 7309c404..6be9ded 100644
--- a/third_party/blink/renderer/modules/eventsource/event_source.h
+++ b/third_party/blink/renderer/modules/eventsource/event_source.h
@@ -78,9 +78,9 @@
 
   State readyState() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(open, kOpen);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(open, kOpen)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
 
   void close();
 
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer.h b/third_party/blink/renderer/modules/filesystem/file_writer.h
index 284b5811..970e12a 100644
--- a/third_party/blink/renderer/modules/filesystem/file_writer.h
+++ b/third_party/blink/renderer/modules/filesystem/file_writer.h
@@ -91,12 +91,12 @@
     return ContextLifecycleObserver::GetExecutionContext();
   }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(writestart, kWritestart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(write, kWrite);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(writeend, kWriteend);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(writestart, kWritestart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(write, kWrite)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(writeend, kWriteend)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/modules/idle/idle_status.h b/third_party/blink/renderer/modules/idle/idle_status.h
index c8f491f6..18d2393 100644
--- a/third_party/blink/renderer/modules/idle/idle_status.h
+++ b/third_party/blink/renderer/modules/idle/idle_status.h
@@ -58,7 +58,7 @@
 
   // IdleStatus IDL interface.
   String state() const;
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
 
   // mojom::blink::IdleMonitor implementation. Invoked on a state change, and
   // causes an event to be dispatched.
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.h b/third_party/blink/renderer/modules/indexeddb/idb_database.h
index a142b2c..cdf4363 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_database.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_database.h
@@ -113,10 +113,10 @@
   void deleteObjectStore(const String& name, ExceptionState&);
   void close();
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(versionchange, kVersionchange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(versionchange, kVersionchange)
 
   // IDBDatabaseCallbacks
   void OnVersionChange(int64_t old_version, int64_t new_version);
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h b/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h
index bb361582..1cce8852 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h
@@ -69,8 +69,8 @@
   // EventTarget
   const AtomicString& InterfaceName() const override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(blocked, kBlocked);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(upgradeneeded, kUpgradeneeded);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(blocked, kBlocked)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(upgradeneeded, kUpgradeneeded)
 
  protected:
   void EnqueueResponse(int64_t old_version) override;
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.h b/third_party/blink/renderer/modules/indexeddb/idb_request.h
index ddb565c..09f222c 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_request.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_request.h
@@ -218,8 +218,8 @@
   WebIDBCallbacks* WebCallbacks() const { return web_callbacks_; }
 #endif  // DCHECK_IS_ON()
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(success, kSuccess);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(success, kSuccess)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
 
   void SetCursorDetails(indexed_db::CursorType, mojom::IDBCursorDirection);
   void SetPendingCursor(IDBCursor*);
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_transaction.h b/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
index bdea907e3..77d68cc 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
@@ -158,9 +158,9 @@
   void SetActive(bool);
   void SetError(DOMException*);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(complete, kComplete);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(complete, kComplete)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
 
   void OnAbort(DOMException*);
   void OnComplete();
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder.h b/third_party/blink/renderer/modules/mediarecorder/media_recorder.h
index 1ee3d18..f1b6d01 100644
--- a/third_party/blink/renderer/modules/mediarecorder/media_recorder.h
+++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder.h
@@ -52,12 +52,12 @@
   uint32_t videoBitsPerSecond() const { return video_bits_per_second_; }
   uint32_t audioBitsPerSecond() const { return audio_bits_per_second_; }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(stop, kStop);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(dataavailable, kDataavailable);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(pause, kPause);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(resume, kResume);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(stop, kStop)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(dataavailable, kDataavailable)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(pause, kPause)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(resume, kResume)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
 
   void start(ExceptionState& exception_state);
   void start(int time_slice, ExceptionState& exception_state);
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.h b/third_party/blink/renderer/modules/mediasource/media_source.h
index 14749ef..57668c09 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source.h
+++ b/third_party/blink/renderer/modules/mediasource/media_source.h
@@ -82,9 +82,9 @@
   void removeSourceBuffer(SourceBuffer*, ExceptionState&);
   void setDuration(double, ExceptionState&);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(sourceopen, kSourceopen);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(sourceended, kSourceended);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(sourceclose, kSourceclose);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(sourceopen, kSourceopen)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(sourceended, kSourceended)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(sourceclose, kSourceclose)
 
   const AtomicString& readyState() const { return ready_state_; }
   void endOfStream(const AtomicString& error, ExceptionState&);
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.h b/third_party/blink/renderer/modules/mediasource/source_buffer.h
index 35a5958..2f12339e 100644
--- a/third_party/blink/renderer/modules/mediasource/source_buffer.h
+++ b/third_party/blink/renderer/modules/mediasource/source_buffer.h
@@ -89,11 +89,11 @@
   void setAppendWindowStart(double, ExceptionState&);
   double appendWindowEnd() const;
   void setAppendWindowEnd(double, ExceptionState&);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(updatestart, kUpdatestart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(update, kUpdate);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(updateend, kUpdateend);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(updatestart, kUpdatestart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(update, kUpdate)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(updateend, kUpdateend)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(abort, kAbort)
   TrackDefaultList* trackDefaults() const { return track_defaults_.Get(); }
   void setTrackDefaults(TrackDefaultList*, ExceptionState&);
 
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer_list.h b/third_party/blink/renderer/modules/mediasource/source_buffer_list.h
index d011c056..61a1a0ba 100644
--- a/third_party/blink/renderer/modules/mediasource/source_buffer_list.h
+++ b/third_party/blink/renderer/modules/mediasource/source_buffer_list.h
@@ -57,8 +57,8 @@
 
   unsigned length() const { return list_.size(); }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(addsourcebuffer, kAddsourcebuffer);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(removesourcebuffer, kRemovesourcebuffer);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(addsourcebuffer, kAddsourcebuffer)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(removesourcebuffer, kRemovesourcebuffer)
 
   SourceBuffer* item(unsigned index) const {
     return (index < list_.size()) ? list_[index].Get() : nullptr;
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.h b/third_party/blink/renderer/modules/mediastream/media_devices.h
index 6f521bd..4381afc 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.h
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.h
@@ -92,7 +92,7 @@
 
   void Trace(blink::Visitor*) override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange)
 
  protected:
   // EventTarget overrides.
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream.h b/third_party/blink/renderer/modules/mediastream/media_stream.h
index 205fc7b..13f90de4 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream.h
+++ b/third_party/blink/renderer/modules/mediastream/media_stream.h
@@ -106,10 +106,10 @@
 
   bool active() const { return descriptor_->Active(); }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(active, kActive);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(inactive, kInactive);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack, kAddtrack);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack, kRemovetrack);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(active, kActive)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(inactive, kInactive)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack, kAddtrack)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack, kRemovetrack)
 
   void TrackEnded();
 
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.h b/third_party/blink/renderer/modules/mediastream/media_stream_track.h
index eafe544..ba90ba9 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_track.h
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.h
@@ -91,9 +91,9 @@
   MediaTrackSettings* getSettings() const;
   ScriptPromise applyConstraints(ScriptState*, const MediaTrackConstraints*);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(mute, kMute);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(unmute, kUnmute);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(ended, kEnded);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(mute, kMute)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(unmute, kUnmute)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(ended, kEnded)
 
   MediaStreamComponent* Component() { return component_; }
   bool Ended() const;
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni
index 031c9045..9b6ff8f 100644
--- a/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -875,6 +875,7 @@
     get_path_info([
                     "accessibility/testing/internals_accessibility.idl",
                     "mediastream/testing/internals_media_stream.idl",
+                    "netinfo/testing/internals_net_info.idl",
                     "peerconnection/testing/internals_rtc_certificate.idl",
                     "peerconnection/testing/internals_rtc_peer_connection.idl",
                     "service_worker/testing/internals_service_worker.idl",
diff --git a/third_party/blink/renderer/modules/netinfo/network_information.h b/third_party/blink/renderer/modules/netinfo/network_information.h
index cadb637f..590ebb1c 100644
--- a/third_party/blink/renderer/modules/netinfo/network_information.h
+++ b/third_party/blink/renderer/modules/netinfo/network_information.h
@@ -61,8 +61,8 @@
 
   void Trace(blink::Visitor*) override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(typechange, kTypechange);  // Deprecated
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(typechange, kTypechange)  // Deprecated
 
  protected:
   // EventTarget overrides.
diff --git a/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.cc b/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.cc
new file mode 100644
index 0000000..448d8e8
--- /dev/null
+++ b/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.cc
@@ -0,0 +1,85 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/netinfo/testing/internals_net_info.h"
+
+#include "third_party/blink/public/platform/web_connection_type.h"
+#include "third_party/blink/public/platform/web_effective_connection_type.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/local_frame_client.h"
+#include "third_party/blink/renderer/core/testing/internals.h"
+#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
+#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
+
+namespace blink {
+
+void InternalsNetInfo::setNetworkConnectionInfoOverride(
+    Internals& internals,
+    bool on_line,
+    const String& type,
+    const String& effective_type,
+    unsigned long http_rtt_msec,
+    double downlink_max_mbps,
+    ExceptionState& exception_state) {
+  WebConnectionType webtype;
+  if (type == "cellular2g") {
+    webtype = kWebConnectionTypeCellular2G;
+  } else if (type == "cellular3g") {
+    webtype = kWebConnectionTypeCellular3G;
+  } else if (type == "cellular4g") {
+    webtype = kWebConnectionTypeCellular4G;
+  } else if (type == "bluetooth") {
+    webtype = kWebConnectionTypeBluetooth;
+  } else if (type == "ethernet") {
+    webtype = kWebConnectionTypeEthernet;
+  } else if (type == "wifi") {
+    webtype = kWebConnectionTypeWifi;
+  } else if (type == "wimax") {
+    webtype = kWebConnectionTypeWimax;
+  } else if (type == "other") {
+    webtype = kWebConnectionTypeOther;
+  } else if (type == "none") {
+    webtype = kWebConnectionTypeNone;
+  } else if (type == "unknown") {
+    webtype = kWebConnectionTypeUnknown;
+  } else {
+    exception_state.ThrowDOMException(
+        DOMExceptionCode::kNotFoundError,
+        ExceptionMessages::FailedToEnumerate("connection type", type));
+    return;
+  }
+  WebEffectiveConnectionType web_effective_type =
+      WebEffectiveConnectionType::kTypeUnknown;
+  if (effective_type == "offline") {
+    web_effective_type = WebEffectiveConnectionType::kTypeOffline;
+  } else if (effective_type == "slow-2g") {
+    web_effective_type = WebEffectiveConnectionType::kTypeSlow2G;
+  } else if (effective_type == "2g") {
+    web_effective_type = WebEffectiveConnectionType::kType2G;
+  } else if (effective_type == "3g") {
+    web_effective_type = WebEffectiveConnectionType::kType3G;
+  } else if (effective_type == "4g") {
+    web_effective_type = WebEffectiveConnectionType::kType4G;
+  } else if (effective_type != "unknown") {
+    exception_state.ThrowDOMException(
+        DOMExceptionCode::kNotFoundError,
+        ExceptionMessages::FailedToEnumerate("effective connection type",
+                                             effective_type));
+    return;
+  }
+  GetNetworkStateNotifier().SetNetworkConnectionInfoOverride(
+      on_line, webtype, web_effective_type, http_rtt_msec, downlink_max_mbps);
+  internals.GetFrame()->Client()->SetEffectiveConnectionTypeForTesting(
+      web_effective_type);
+}
+
+void InternalsNetInfo::setSaveDataEnabled(Internals&, bool enabled) {
+  GetNetworkStateNotifier().SetSaveDataEnabledOverride(enabled);
+}
+
+void InternalsNetInfo::clearNetworkConnectionInfoOverride(Internals&) {
+  GetNetworkStateNotifier().ClearOverride();
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.h b/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.h
new file mode 100644
index 0000000..1937e61
--- /dev/null
+++ b/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.h
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NETINFO_TESTING_INTERNALS_NET_INFO_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_NETINFO_TESTING_INTERNALS_NET_INFO_H_
+
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class Internals;
+
+class InternalsNetInfo {
+  STATIC_ONLY(InternalsNetInfo);
+
+ public:
+  static void setNetworkConnectionInfoOverride(Internals& internals,
+                                               bool on_line,
+                                               const String& type,
+                                               const String& effective_type,
+                                               unsigned long http_rtt_msec,
+                                               double downlink_max_mbps,
+                                               ExceptionState& exception_state);
+  static void setSaveDataEnabled(Internals&, bool enabled);
+
+  static void clearNetworkConnectionInfoOverride(Internals&);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_NETINFO_TESTING_INTERNALS_NET_INFO_H_
diff --git a/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.idl b/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.idl
new file mode 100644
index 0000000..7b976de0
--- /dev/null
+++ b/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.idl
@@ -0,0 +1,12 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+    ImplementedAs=InternalsNetInfo
+] partial interface Internals {
+    // You must call clearNetworkConnectionInfoOverride() at the end.
+    [RaisesException] void setNetworkConnectionInfoOverride(boolean onLine, DOMString type, EffectiveConnectionType effective_type, unsigned long http_rtt_msec, double downlink_max_mbps);
+    void setSaveDataEnabled(boolean enabled);
+    void clearNetworkConnectionInfoOverride();
+};
diff --git a/third_party/blink/renderer/modules/notifications/notification.h b/third_party/blink/renderer/modules/notifications/notification.h
index 1a19e3f..843b1933 100644
--- a/third_party/blink/renderer/modules/notifications/notification.h
+++ b/third_party/blink/renderer/modules/notifications/notification.h
@@ -92,10 +92,10 @@
 
   void close();
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(click, kClick);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(show, kShow);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(click, kClick)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(show, kShow)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose)
 
   // NonPersistentNotificationListener interface.
   void OnShow() override;
diff --git a/third_party/blink/renderer/modules/notifications/service_worker_global_scope_notifications.h b/third_party/blink/renderer/modules/notifications/service_worker_global_scope_notifications.h
index a059f9b..9e53798 100644
--- a/third_party/blink/renderer/modules/notifications/service_worker_global_scope_notifications.h
+++ b/third_party/blink/renderer/modules/notifications/service_worker_global_scope_notifications.h
@@ -14,8 +14,8 @@
   STATIC_ONLY(ServiceWorkerGlobalScopeNotifications);
 
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(notificationclick, kNotificationclick);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(notificationclose, kNotificationclose);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(notificationclick, kNotificationclick)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(notificationclose, kNotificationclose)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_app_service_worker_global_scope.h b/third_party/blink/renderer/modules/payments/payment_app_service_worker_global_scope.h
index 47242ed..d702ec3 100644
--- a/third_party/blink/renderer/modules/payments/payment_app_service_worker_global_scope.h
+++ b/third_party/blink/renderer/modules/payments/payment_app_service_worker_global_scope.h
@@ -14,9 +14,9 @@
   STATIC_ONLY(PaymentAppServiceWorkerGlobalScope);
 
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abortpayment, kAbortpayment);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canmakepayment, kCanmakepayment);
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(paymentrequest, kPaymentrequest);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abortpayment, kAbortpayment)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canmakepayment, kCanmakepayment)
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(paymentrequest, kPaymentrequest)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_request.h b/third_party/blink/renderer/modules/payments/payment_request.h
index dcce1e7..8a276a3 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.h
+++ b/third_party/blink/renderer/modules/payments/payment_request.h
@@ -74,10 +74,9 @@
   const String& shippingOption() const { return shipping_option_; }
   const String& shippingType() const { return shipping_type_; }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(shippingaddresschange,
-                                  kShippingaddresschange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(shippingoptionchange, kShippingoptionchange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(paymentmethodchange, kPaymentmethodchange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(shippingaddresschange, kShippingaddresschange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(shippingoptionchange, kShippingoptionchange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(paymentmethodchange, kPaymentmethodchange)
 
   ScriptPromise canMakePayment(ScriptState*);
   ScriptPromise hasEnrolledInstrument(ScriptState*);
diff --git a/third_party/blink/renderer/modules/payments/payment_response.h b/third_party/blink/renderer/modules/payments/payment_response.h
index 8d78bce..1d77fab 100644
--- a/third_party/blink/renderer/modules/payments/payment_response.h
+++ b/third_party/blink/renderer/modules/payments/payment_response.h
@@ -64,7 +64,7 @@
 
   bool HasPendingActivity() const override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(payerdetailchange, kPayerdetailchange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(payerdetailchange, kPayerdetailchange)
 
   const AtomicString& InterfaceName() const override;
   ExecutionContext* GetExecutionContext() const override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
index c1d65f0..a1e779a7 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
@@ -97,11 +97,11 @@
 
   void close();
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(open, kOpen);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(bufferedamountlow, kBufferedamountlow);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(open, kOpen)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(bufferedamountlow, kBufferedamountlow)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
 
   // EventTarget
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h
index 7da68aa..523aa04 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h
@@ -49,8 +49,8 @@
   String state() const;
   const HeapVector<Member<DOMArrayBuffer>>& getRemoteCertificates() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
 
   // DtlsTransportProxy::Delegate
   void OnStartCompleted(webrtc::DtlsTransportInformation info) override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
index 8a80a35..1a83503 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
@@ -61,7 +61,7 @@
                   int inter_tone_gap,
                   ExceptionState&);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(tonechange, kTonechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(tonechange, kTonechange)
 
   // EventTarget
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
index 9ba6eadf..ec5e3296 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
@@ -107,11 +107,11 @@
   void stop();
   void addRemoteCandidate(RTCIceCandidate* remote_candidate,
                           ExceptionState& exception_state);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(gatheringstatechange, kGatheringstatechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(gatheringstatechange, kGatheringstatechange)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(selectedcandidatepairchange,
-                                  kSelectedcandidatepairchange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate, kIcecandidate);
+                                  kSelectedcandidatepairchange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate, kIcecandidate)
 
   // EventTarget overrides.
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
index d60f8be..5d72237 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -226,7 +226,7 @@
                                     ExceptionState&);
   RTCRtpSender* addTrack(MediaStreamTrack*, MediaStreamVector, ExceptionState&);
   void removeTrack(RTCRtpSender*, ExceptionState&);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(track, kTrack);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(track, kTrack)
 
   RTCDataChannel* createDataChannel(ScriptState*,
                                     String label,
@@ -247,18 +247,17 @@
   bool ShouldFireDefaultCallbacks() { return !closed_ && !stopped_; }
   bool ShouldFireGetStatsCallback() { return !stopped_; }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(negotiationneeded, kNegotiationneeded);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate, kIcecandidate);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(signalingstatechange, kSignalingstatechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(addstream, kAddstream);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(removestream, kRemovestream);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(negotiationneeded, kNegotiationneeded)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate, kIcecandidate)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(signalingstatechange, kSignalingstatechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(addstream, kAddstream)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(removestream, kRemovestream)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(iceconnectionstatechange,
-                                  kIceconnectionstatechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionstatechange,
-                                  kConnectionstatechange);
+                                  kIceconnectionstatechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionstatechange, kConnectionstatechange)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(icegatheringstatechange,
-                                  kIcegatheringstatechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(datachannel, kDatachannel);
+                                  kIcegatheringstatechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(datachannel, kDatachannel)
 
   // Utility to note result of CreateOffer / CreateAnswer
   void NoteSdpCreated(const RTCSessionDescription&);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h b/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
index dac8d940..6a3048e 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
@@ -105,7 +105,7 @@
   ScriptPromise waitForReadable(ScriptState* script_state,
                                 uint32_t amount,
                                 ExceptionState& exception_state);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
 
   // EventTarget overrides.
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
index eaebe1e..3ca21b6 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
@@ -127,9 +127,9 @@
   // Resolves the promise with an RTCQuicTransportStats dictionary.
   ScriptPromise getStats(ScriptState* script_state,
                          ExceptionState& exception_state);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(quicstream, kQuicstream);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(quicstream, kQuicstream)
 
   // EventTarget overrides.
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/permissions/permission_status.h b/third_party/blink/renderer/modules/permissions/permission_status.h
index 55b5074..cb6b21c 100644
--- a/third_party/blink/renderer/modules/permissions/permission_status.h
+++ b/third_party/blink/renderer/modules/permissions/permission_status.h
@@ -60,7 +60,7 @@
 
   String state() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h b/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h
index fe08f25..13981d8 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h
+++ b/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h
@@ -34,11 +34,11 @@
                                   bool);
 
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(enterpictureinpicture,
-                                         kEnterpictureinpicture);
+                                         kEnterpictureinpicture)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(leavepictureinpicture,
-                                         kLeavepictureinpicture);
+                                         kLeavepictureinpicture)
   DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pictureinpicturecontrolclick,
-                                         kPictureinpicturecontrolclick);
+                                         kPictureinpicturecontrolclick)
 
   static std::vector<PictureInPictureControlInfo>
   ToPictureInPictureControlInfoVector(
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h
index e3437349..061060a 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h
+++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h
@@ -35,7 +35,7 @@
   // Called when the Picture-in-Picture window is resized.
   void OnResize(const WebSize&);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(resize, kResize);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(resize, kResize)
 
   // EventTarget overrides.
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/presentation/presentation_availability.h b/third_party/blink/renderer/modules/presentation/presentation_availability.h
index b2e24824..b8e6f78e 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_availability.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_availability.h
@@ -62,7 +62,7 @@
 
   bool value() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection.h b/third_party/blink/renderer/modules/presentation/presentation_connection.h
index 2ea246bc..f425188 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_connection.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_connection.h
@@ -64,10 +64,10 @@
   String binaryType() const;
   void setBinaryType(const String&);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(terminate, kTerminate);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(terminate, kTerminate)
 
   // Returns true if this connection's id equals to |id| and its url equals to
   // |url|.
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection_list.h b/third_party/blink/renderer/modules/presentation/presentation_connection_list.h
index e0aa072d..f6d8d8f8 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_connection_list.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_connection_list.h
@@ -34,7 +34,7 @@
 
   // PresentationConnectionList.idl implementation.
   const HeapVector<Member<ReceiverPresentationConnection>>& connections() const;
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable, kConnectionavailable);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable, kConnectionavailable)
 
   void AddConnection(ReceiverPresentationConnection*);
   // Remove connection from connection list. Returns true if connection is
diff --git a/third_party/blink/renderer/modules/presentation/presentation_request.h b/third_party/blink/renderer/modules/presentation/presentation_request.h
index f6471b9..3a7015e 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_request.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_request.h
@@ -51,7 +51,7 @@
 
   const Vector<KURL>& Urls() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable, kConnectionavailable);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable, kConnectionavailable)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/modules/push_messaging/service_worker_global_scope_push.h b/third_party/blink/renderer/modules/push_messaging/service_worker_global_scope_push.h
index 2411e98..63ce901 100644
--- a/third_party/blink/renderer/modules/push_messaging/service_worker_global_scope_push.h
+++ b/third_party/blink/renderer/modules/push_messaging/service_worker_global_scope_push.h
@@ -11,7 +11,7 @@
 
 class ServiceWorkerGlobalScopePush {
  public:
-  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(push, kPush);
+  DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(push, kPush)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.h b/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
index 58ba977..c483c4ee 100644
--- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
+++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
@@ -133,9 +133,9 @@
   // ContextLifecycleObserver implementation.
   void ContextDestroyed(ExecutionContext*) override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connecting, kConnecting);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connecting, kConnecting)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h b/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h
index 2864c92..b4176ba 100644
--- a/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h
+++ b/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h
@@ -45,7 +45,7 @@
   ScriptPromise lock(ScriptState*, const AtomicString& orientation);
   void unlock();
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
 
   // Helper being used by this class and LockOrientationCallback.
   static const AtomicString& OrientationTypeToString(WebScreenOrientationType);
diff --git a/third_party/blink/renderer/modules/sensor/sensor.h b/third_party/blink/renderer/modules/sensor/sensor.h
index de75c196..bc43314d 100644
--- a/third_party/blink/renderer/modules/sensor/sensor.h
+++ b/third_party/blink/renderer/modules/sensor/sensor.h
@@ -54,9 +54,9 @@
   bool hasReading() const;
   DOMHighResTimeStamp timestamp(ScriptState*, bool& is_null) const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(reading, kReading);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(activate, kActivate);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(reading, kReading)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(activate, kActivate)
 
   // ActiveScriptWrappable overrides.
   bool HasPendingActivity() const override;
diff --git a/third_party/blink/renderer/modules/serial/serial.h b/third_party/blink/renderer/modules/serial/serial.h
index 02c0cad..195ec073 100644
--- a/third_party/blink/renderer/modules/serial/serial.h
+++ b/third_party/blink/renderer/modules/serial/serial.h
@@ -36,8 +36,8 @@
   ExecutionContext* GetExecutionContext() const override;
   const AtomicString& InterfaceName() const override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect)
   ScriptPromise getPorts(ScriptState*);
   ScriptPromise requestPort(ScriptState*, const SerialPortRequestOptions*);
 
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker.h b/third_party/blink/renderer/modules/service_worker/service_worker.h
index a39db6b..d31e769 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker.h
@@ -79,7 +79,7 @@
 
   String scriptURL() const;
   String state() const;
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
 
   ServiceWorker* ToServiceWorker() override { return this; }
 
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container.h b/third_party/blink/renderer/modules/service_worker/service_worker_container.h
index 448bb62..5905334 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_container.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_container.h
@@ -104,7 +104,7 @@
   ExecutionContext* GetExecutionContext() const override;
   const AtomicString& InterfaceName() const override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(controllerchange, kControllerchange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(controllerchange, kControllerchange)
 
   void setOnmessage(EventListener* listener);
   EventListener* onmessage();
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
index a37587508..c41b1fd 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -140,10 +140,10 @@
   int WillStartTask();
   void DidEndTask(int task_id);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(install, kInstall);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(activate, kActivate);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(fetch, kFetch);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(install, kInstall)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(activate, kActivate)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(fetch, kFetch)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_registration.h b/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
index ecfee8e..6c73d948 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
@@ -84,7 +84,7 @@
   ScriptPromise update(ScriptState*);
   ScriptPromise unregister(ScriptState*);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(updatefound, kUpdatefound);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(updatefound, kUpdatefound)
 
   ~ServiceWorkerRegistration() override;
 
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition.h b/third_party/blink/renderer/modules/speech/speech_recognition.h
index 6ed3b5a..8d6ffa2 100644
--- a/third_party/blink/renderer/modules/speech/speech_recognition.h
+++ b/third_party/blink/renderer/modules/speech/speech_recognition.h
@@ -108,17 +108,17 @@
   // PageVisibilityObserver
   void PageVisibilityChanged() override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(audiostart, kAudiostart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(soundstart, kSoundstart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(speechstart, kSpeechstart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(speechend, kSpeechend);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(soundend, kSoundend);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(audioend, kAudioend);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(result, kResult);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(nomatch, kNomatch);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(audiostart, kAudiostart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(soundstart, kSoundstart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(speechstart, kSpeechstart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(speechend, kSpeechend)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(soundend, kSoundend)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(audioend, kAudioend)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(result, kResult)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(nomatch, kNomatch)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd)
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/modules/speech/speech_synthesis.h b/third_party/blink/renderer/modules/speech/speech_synthesis.h
index da6bf9f..d351d3a 100644
--- a/third_party/blink/renderer/modules/speech/speech_synthesis.h
+++ b/third_party/blink/renderer/modules/speech/speech_synthesis.h
@@ -65,7 +65,7 @@
   // Used in testing to use a mock platform synthesizer
   void SetPlatformSynthesizer(PlatformSpeechSynthesizer*);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(voiceschanged, kVoiceschanged);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(voiceschanged, kVoiceschanged)
 
   ExecutionContext* GetExecutionContext() const override {
     return ContextClient::GetExecutionContext();
diff --git a/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h b/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h
index 0395f3f4..a446860 100644
--- a/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h
+++ b/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h
@@ -70,13 +70,13 @@
     platform_utterance_->SetStartTime(start_time);
   }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(pause, kPause);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(resume, kResume);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(mark, kMark);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(boundary, kBoundary);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(pause, kPause)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(resume, kResume)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(mark, kMark)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(boundary, kBoundary)
 
   ExecutionContext* GetExecutionContext() const override {
     return ContextClient::GetExecutionContext();
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock.h b/third_party/blink/renderer/modules/wake_lock/wake_lock.h
index 3858947..c2e7f64 100644
--- a/third_party/blink/renderer/modules/wake_lock/wake_lock.h
+++ b/third_party/blink/renderer/modules/wake_lock/wake_lock.h
@@ -35,7 +35,7 @@
   // wake_lock.idl implementation
   AtomicString type() const;
   bool active() const;
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(activechange, kActivechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(activechange, kActivechange)
   WakeLockRequest* createRequest();
 
   // Called by NavigatorWakeLock to create Screen Wake Lock
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
index ae5c54e3..aae6fd76 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
@@ -114,7 +114,7 @@
   // IDL
   AudioParamMap* parameters() const;
   MessagePort* port() const;
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(processorerror, kProcessorerror);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(processorerror, kProcessorerror)
 
   void FireProcessorError();
 
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
index e02b314..ce9434b 100644
--- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h
+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
@@ -280,7 +280,7 @@
   const AtomicString& InterfaceName() const final;
   ExecutionContext* GetExecutionContext() const final;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
 
   void StartRendering();
 
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
index ebef704..7708d94d 100644
--- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
@@ -70,7 +70,7 @@
 
   bool HasRealtimeConstraint() final { return false; }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(complete, kComplete);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(complete, kComplete)
 
   // Fire completion event when the rendering is finished.
   void FireCompletionEvent();
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.h b/third_party/blink/renderer/modules/webaudio/script_processor_node.h
index 11a7936a..6dc2433 100644
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.h
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.h
@@ -145,7 +145,7 @@
                       uint32_t number_of_input_channels,
                       uint32_t number_of_output_channels);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(audioprocess, kAudioprocess);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(audioprocess, kAudioprocess)
   uint32_t bufferSize() const;
 
   // ScriptWrappable
diff --git a/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.idl b/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.idl
index 8c468c6..e8110a1 100644
--- a/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.idl
+++ b/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.idl
@@ -4,8 +4,6 @@
 
 // https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query_webgl2/
 
-typedef unsigned long long GLuint64EXT;
-
 [
     DoNotCheckConstants,
     NoInterfaceObject
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index a77c320..5f6bc49 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -1749,6 +1749,6 @@
 }  // namespace blink
 
 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
-    blink::WebGLRenderingContextBase::TextureUnitState);
+    blink::WebGLRenderingContextBase::TextureUnitState)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_BASE_H_
diff --git a/third_party/blink/renderer/modules/webmidi/midi_port.h b/third_party/blink/renderer/modules/webmidi/midi_port.h
index 2b48a3e..8682fe2 100644
--- a/third_party/blink/renderer/modules/webmidi/midi_port.h
+++ b/third_party/blink/renderer/modules/webmidi/midi_port.h
@@ -79,7 +79,7 @@
 
   void Trace(blink::Visitor*) override;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
 
   // EventTarget
   const AtomicString& InterfaceName() const override {
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.h b/third_party/blink/renderer/modules/websockets/dom_websocket.h
index cdd772ba..199e796 100644
--- a/third_party/blink/renderer/modules/websockets/dom_websocket.h
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket.h
@@ -113,10 +113,10 @@
   String binaryType() const;
   void setBinaryType(const String&);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(open, kOpen);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(open, kOpen)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose)
 
   // EventTarget functions.
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/webusb/usb.h b/third_party/blink/renderer/modules/webusb/usb.h
index f485bae..b6b54f6 100644
--- a/third_party/blink/renderer/modules/webusb/usb.h
+++ b/third_party/blink/renderer/modules/webusb/usb.h
@@ -44,8 +44,8 @@
   // USB.idl
   ScriptPromise getDevices(ScriptState*);
   ScriptPromise requestDevice(ScriptState*, const USBDeviceRequestOptions*);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect)
 
   // EventTarget overrides.
   ExecutionContext* GetExecutionContext() const override;
diff --git a/third_party/blink/renderer/modules/xr/xr.h b/third_party/blink/renderer/modules/xr/xr.h
index 59c82e1e..0822298 100644
--- a/third_party/blink/renderer/modules/xr/xr.h
+++ b/third_party/blink/renderer/modules/xr/xr.h
@@ -37,7 +37,7 @@
 
   explicit XR(LocalFrame& frame, int64_t ukm_source_id_);
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange)
 
   ScriptPromise supportsSessionMode(ScriptState*, const String&);
   ScriptPromise requestSession(ScriptState*, const XRSessionCreationOptions*);
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h
index 1b1f38b8..41145a0 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.h
+++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -78,14 +78,14 @@
 
   bool immersive() const;
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(blur, kBlur);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(focus, kFocus);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(resetpose, kResetpose);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(blur, kBlur)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(focus, kFocus)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(resetpose, kResetpose)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd)
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart, kSelectstart);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(selectend, kSelectend);
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(select, kSelect);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart, kSelectstart)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(selectend, kSelectend)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(select, kSelect)
 
   void updateRenderState(XRRenderStateInit*, ExceptionState&);
   ScriptPromise requestReferenceSpace(ScriptState*,
diff --git a/third_party/blink/renderer/modules/xr/xr_space.h b/third_party/blink/renderer/modules/xr/xr_space.h
index 9cc6804..acfdbbe 100644
--- a/third_party/blink/renderer/modules/xr/xr_space.h
+++ b/third_party/blink/renderer/modules/xr/xr_space.h
@@ -27,7 +27,7 @@
 
   XRSession* session() const { return session_; }
 
-  DEFINE_ATTRIBUTE_EVENT_LISTENER(reset, kReset);
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(reset, kReset)
 
   // EventTarget overrides.
   ExecutionContext* GetExecutionContext() const override;
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc b/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
index 22dfb45..7dbe8b2 100644
--- a/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
+++ b/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
@@ -203,6 +203,18 @@
       std::move(string), ParkableStringImpl::ParkableState::kParkable);
   unparked_strings_.insert(raw_ptr, new_parkable_string.get());
   ScheduleAgingTaskIfNeeded();
+
+  // Lazy registration because registering too early can cause crashes on Linux,
+  // see crbug.com/930117, and registering without any strings is pointless
+  // anyway.
+  if (!did_register_memory_pressure_listener_) {
+    // No need to ever unregister, as the only ParkableStringManager instance
+    // lives forever.
+    MemoryPressureListenerRegistry::Instance().RegisterClient(
+        MakeGarbageCollected<OnPurgeMemoryListener>());
+    did_register_memory_pressure_listener_ = true;
+  }
+
   return new_parkable_string;
 }
 
@@ -405,6 +417,7 @@
   waiting_to_record_stats_ = false;
   has_pending_aging_task_ = false;
   should_record_stats_ = false;
+  did_register_memory_pressure_listener_ = false;
   unparked_strings_.clear();
   parked_strings_.clear();
 }
@@ -414,12 +427,8 @@
       waiting_to_record_stats_(false),
       has_pending_aging_task_(false),
       should_record_stats_(false),
+      did_register_memory_pressure_listener_(false),
       unparked_strings_(),
-      parked_strings_() {
-  // No need to ever unregister, as the only ParkableStringManager instance
-  // lives forever.
-  MemoryPressureListenerRegistry::Instance().RegisterClient(
-      MakeGarbageCollected<OnPurgeMemoryListener>());
-}
+      parked_strings_() {}
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string_manager.h b/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
index 20e510d..45492c8 100644
--- a/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
+++ b/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
@@ -93,6 +93,7 @@
   bool waiting_to_record_stats_;
   bool has_pending_aging_task_;
   bool should_record_stats_;
+  bool did_register_memory_pressure_listener_;
   HashMap<StringImpl*, ParkableStringImpl*, PtrHash<StringImpl>>
       unparked_strings_;
   HashSet<ParkableStringImpl*, PtrHash<ParkableStringImpl>> parked_strings_;
diff --git a/third_party/blink/renderer/platform/geometry/float_size.h b/third_party/blink/renderer/platform/geometry/float_size.h
index b7989075..e17c4941 100644
--- a/third_party/blink/renderer/platform/geometry/float_size.h
+++ b/third_party/blink/renderer/platform/geometry/float_size.h
@@ -218,6 +218,6 @@
 }  // namespace blink
 
 // Allows this class to be stored in a HeapVector.
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::FloatSize);
+WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::FloatSize)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_FLOAT_SIZE_H_
diff --git a/third_party/blink/renderer/platform/geometry/int_point.h b/third_party/blink/renderer/platform/geometry/int_point.h
index 67e3f0e..003ee8b 100644
--- a/third_party/blink/renderer/platform/geometry/int_point.h
+++ b/third_party/blink/renderer/platform/geometry/int_point.h
@@ -168,6 +168,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::IntPoint);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::IntPoint)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_INT_POINT_H_
diff --git a/third_party/blink/renderer/platform/geometry/int_rect.h b/third_party/blink/renderer/platform/geometry/int_rect.h
index 6d07e19..0f0dddc 100644
--- a/third_party/blink/renderer/platform/geometry/int_rect.h
+++ b/third_party/blink/renderer/platform/geometry/int_rect.h
@@ -238,6 +238,6 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::IntRect);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::IntRect)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_INT_RECT_H_
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 a09b609e..8fa8252 100644
--- a/third_party/blink/renderer/platform/heap/heap_compact_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_compact_test.cc
@@ -91,7 +91,7 @@
 using IntMap = blink::HeapHashMap<blink::Member<IntWrapper>, int>;
 // TODO(sof): decide if this ought to be a global trait specialization.
 // (i.e., for HeapHash*<T>.)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(IntMap);
+WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(IntMap)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc
index 5b181f6..2ab06dda 100644
--- a/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -1446,11 +1446,11 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::TerminatedArrayItem);
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObject);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::TerminatedArrayItem)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObject)
 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
-    blink::VectorObjectInheritedTrace);
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObjectNoTrace);
+    blink::VectorObjectInheritedTrace)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObjectNoTrace)
 
 namespace blink {
 
@@ -4311,7 +4311,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::InlinedVectorObject);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::InlinedVectorObject)
 
 namespace blink {
 
@@ -5728,7 +5728,7 @@
 
 }  // namespace blink
 
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::PartObjectWithRef);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::PartObjectWithRef)
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
index d9148b9..2340a92f 100644
--- a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
+++ b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
@@ -32,7 +32,7 @@
 
 void UnifiedHeapMarkingVisitor::WriteBarrier(
     const TraceWrapperV8Reference<v8::Value>& object) {
-  if (!ThreadState::IsAnyIncrementalMarking())
+  if (object.IsEmpty() || !ThreadState::IsAnyIncrementalMarking())
     return;
 
   ThreadState* thread_state = ThreadState::Current();
diff --git a/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc b/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc
index ff926caa..0cc9ba6 100644
--- a/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc
@@ -43,11 +43,19 @@
     if (result == Result::kOk) {
       *available = std::min(*available, lookahead_bytes_);
       if (*available == 0) {
+        result = bytes_consumer_->EndRead(0);
         *buffer = nullptr;
-        result = Result::kShouldWait;
-        task_runner_->PostTask(
-            FROM_HERE, base::BindOnce(&DelegatingBytesConsumer::OnStateChange,
-                                      WrapPersistent(this)));
+        if (result == Result::kOk) {
+          result = Result::kShouldWait;
+          if (in_on_state_change_) {
+            waiting_for_lookahead_bytes_ = true;
+          } else {
+            task_runner_->PostTask(
+                FROM_HERE,
+                base::BindOnce(&DelegatingBytesConsumer::OnStateChange,
+                               WrapPersistent(this)));
+          }
+        }
       }
     }
     HandleResult(result);
@@ -112,7 +120,7 @@
     bytes_consumer_->Cancel();
 
     if (in_on_state_change_) {
-      has_pending_signal_ = true;
+      has_pending_state_change_signal_ = true;
       return;
     }
     task_runner_->PostTask(
@@ -138,34 +146,49 @@
 
   void OnStateChange() override {
     DCHECK(!in_on_state_change_);
-    base::AutoReset<bool> auto_reset(&in_on_state_change_, true);
+    DCHECK(!has_pending_state_change_signal_);
+    DCHECK(!waiting_for_lookahead_bytes_);
+    base::AutoReset<bool> auto_reset_for_in_on_state_change(
+        &in_on_state_change_, true);
+    base::AutoReset<bool> auto_reset_for_has_pending_state_change_signal(
+        &has_pending_state_change_signal_, false);
+    base::AutoReset<bool> auto_reset_for_waiting_for_lookahead_bytes(
+        &waiting_for_lookahead_bytes_, false);
 
     if (loader_->IsAborted() || loader_->IsSuspended() ||
         state_ == State::kCancelled) {
       return;
     }
-
-    // Peek available bytes from |bytes_consumer_| and report them to
-    // |loader_|.
-    const char* buffer = nullptr;
-    size_t available = 0;
-    // Poissible state change caused by BeginRead will be realized by the
-    // following logic, so we don't need to worry about it here.
-    auto result = bytes_consumer_->BeginRead(&buffer, &available);
-    if (result == Result::kOk) {
-      if (lookahead_bytes_ < available) {
-        loader_->DidReceiveData(base::make_span(buffer + lookahead_bytes_,
-                                                available - lookahead_bytes_));
-        lookahead_bytes_ = available;
-      }
-      // Poissible state change caused by EndRead will be realized by the
+    while (state_ == State::kLoading) {
+      // Peek available bytes from |bytes_consumer_| and report them to
+      // |loader_|.
+      const char* buffer = nullptr;
+      size_t available = 0;
+      // Possible state change caused by BeginRead will be realized by the
       // following logic, so we don't need to worry about it here.
-      Result unused = bytes_consumer_->EndRead(0);
-      ALLOW_UNUSED_LOCAL(unused);
-    }
-
-    if (bytes_consumer_client_) {
-      bytes_consumer_client_->OnStateChange();
+      auto result = bytes_consumer_->BeginRead(&buffer, &available);
+      if (result == Result::kOk) {
+        if (lookahead_bytes_ < available) {
+          loader_->DidReceiveData(base::make_span(
+              buffer + lookahead_bytes_, available - lookahead_bytes_));
+          lookahead_bytes_ = available;
+        }
+        // Possible state change caused by EndRead will be realized by the
+        // following logic, so we don't need to worry about it here.
+        result = bytes_consumer_->EndRead(0);
+      }
+      waiting_for_lookahead_bytes_ = false;
+      if ((result == Result::kOk || result == Result::kShouldWait) &&
+          lookahead_bytes_ == 0) {
+        // We have no information to notify the client.
+        break;
+      }
+      if (bytes_consumer_client_) {
+        bytes_consumer_client_->OnStateChange();
+      }
+      if (!waiting_for_lookahead_bytes_) {
+        break;
+      }
     }
 
     switch (GetPublicState()) {
@@ -179,8 +202,7 @@
         break;
     }
 
-    if (has_pending_signal_) {
-      has_pending_signal_ = false;
+    if (has_pending_state_change_signal_) {
       switch (state_) {
         case State::kLoading:
           NOTREACHED();
@@ -221,7 +243,7 @@
     if (result == Result::kDone) {
       state_ = State::kDone;
       if (in_on_state_change_) {
-        has_pending_signal_ = true;
+        has_pending_state_change_signal_ = true;
       } else {
         task_runner_->PostTask(
             FROM_HERE, base::BindOnce(&ResponseBodyLoader::DidFinishLoadingBody,
@@ -232,7 +254,7 @@
     if (result == Result::kError) {
       state_ = State::kErrored;
       if (in_on_state_change_) {
-        has_pending_signal_ = true;
+        has_pending_state_change_signal_ = true;
       } else {
         task_runner_->PostTask(
             FROM_HERE, base::BindOnce(&ResponseBodyLoader::DidFailLoadingBody,
@@ -250,7 +272,11 @@
   size_t lookahead_bytes_ = 0;
   State state_ = State::kLoading;
   bool in_on_state_change_ = false;
-  bool has_pending_signal_ = false;
+  // Set when |state_| changes in OnStateChange.
+  bool has_pending_state_change_signal_ = false;
+  // Set when BeginRead returns kShouldWait due to |lookahead_bytes_| in
+  // OnStateChange.
+  bool waiting_for_lookahead_bytes_ = false;
 };
 
 ResponseBodyLoader::ResponseBodyLoader(
diff --git a/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc b/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc
index f027e17..401bed1 100644
--- a/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc
+++ b/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc
@@ -18,6 +18,7 @@
 
 BytesConsumer::Result ReplayingBytesConsumer::BeginRead(const char** buffer,
                                                         size_t* available) {
+  DCHECK(!is_in_two_phase_read_);
   ++notification_token_;
   if (commands_.IsEmpty()) {
     switch (state_) {
@@ -37,6 +38,7 @@
       DCHECK_LE(offset_, command.Body().size());
       *buffer = command.Body().data() + offset_;
       *available = command.Body().size() - offset_;
+      is_in_two_phase_read_ = true;
       return Result::kOk;
     case Command::kDone:
       commands_.pop_front();
@@ -61,7 +63,10 @@
 }
 
 BytesConsumer::Result ReplayingBytesConsumer::EndRead(size_t read) {
+  DCHECK(is_in_two_phase_read_);
   DCHECK(!commands_.IsEmpty());
+
+  is_in_two_phase_read_ = false;
   const Command& command = commands_[0];
   const auto name = command.GetName();
   DCHECK(name == Command::kData || name == Command::kDataAndDone);
diff --git a/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h b/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h
index c516846..e3dc0ae 100644
--- a/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h
+++ b/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h
@@ -80,6 +80,7 @@
   BytesConsumer::Error error_;
   int notification_token_ = 0;
   bool is_cancelled_ = false;
+  bool is_in_two_phase_read_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc b/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
index 7a40ce4..34f9281 100644
--- a/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
+++ b/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
@@ -51,7 +51,7 @@
       : internal_(other.internal_) {}
   ~DummyWebRTCRtpSender() override {}
 
-  scoped_refptr<DummyRtpSenderInternal> internal() const { return internal_; };
+  scoped_refptr<DummyRtpSenderInternal> internal() const { return internal_; }
 
   std::unique_ptr<WebRTCRtpSender> ShallowCopy() const override {
     return nullptr;
diff --git a/third_party/blink/renderer/platform/wtf/size_assertions.h b/third_party/blink/renderer/platform/wtf/size_assertions.h
index a5de40f..434f5bd5 100644
--- a/third_party/blink/renderer/platform/wtf/size_assertions.h
+++ b/third_party/blink/renderer/platform/wtf/size_assertions.h
@@ -24,6 +24,6 @@
 }  // namespace WTF
 
 #define ASSERT_SIZE(className, sameSizeAsClassName) \
-  static_assert(WTF::assert_size<className, sameSizeAsClassName>::value, "");
+  static_assert(WTF::assert_size<className, sameSizeAsClassName>::value, "")
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_SIZE_ASSERTIONS_H_
diff --git a/third_party/blink/renderer/platform/wtf/text/atomic_string.h b/third_party/blink/renderer/platform/wtf/text/atomic_string.h
index 30e88b1..9255761 100644
--- a/third_party/blink/renderer/platform/wtf/text/atomic_string.h
+++ b/third_party/blink/renderer/platform/wtf/text/atomic_string.h
@@ -316,7 +316,7 @@
 
 }  // namespace WTF
 
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(AtomicString);
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(AtomicString)
 
 using WTF::AtomicString;
 using WTF::g_null_atom;
diff --git a/third_party/blink/renderer/platform/wtf/text/wtf_string.h b/third_party/blink/renderer/platform/wtf/text/wtf_string.h
index bb17132..231cfcc9 100644
--- a/third_party/blink/renderer/platform/wtf/text/wtf_string.h
+++ b/third_party/blink/renderer/platform/wtf/text/wtf_string.h
@@ -667,7 +667,7 @@
 
 }  // namespace WTF
 
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(String);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(String)
 
 using WTF::CString;
 using WTF::kStrictUTF8Conversion;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 4d4e30e0..68afc23 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -394,7 +394,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 [ Failure ]
+crbug.com/884239 virtual/threaded/animations/animationworklet/worklet-animation-local-time-undefined.html [ Failure Pass ]
 # 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 ]
@@ -3074,7 +3074,6 @@
 crbug.com/918664 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/block-size-with-min-or-max-content-table-1a.html [ Failure Pass ]
 
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html [ Timeout ]
 crbug.com/626703 crbug.com/930297 [ Linux ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Timeout Pass Failure ]
 crbug.com/626703 [ Win7 ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html [ Failure ]
@@ -6009,6 +6008,7 @@
 # Race: The RTCIceConnectionState can become "connected" before getStats()
 # returns candidate-pair whose state is "succeeded", this sounds like a
 # contradiction.
+crbug.com/926170 external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html [ Pass Timeout ]
 crbug.com/926170 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html [ Pass Timeout ]
 
 # Sheriff 2019-01-18
@@ -6081,7 +6081,6 @@
 
 # Sheriff 2019-02-06
 crbug.com/929122 [ Linux ] external/wpt/html/dom/interfaces.worker.html [ Timeout Failure ]
-crbug.com/929355 [ Linux ] external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Pass Failure ]
 crbug.com/929435 [ Mac ] external/wpt/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html [ Pass Failure ]
 
 # Sheriff 2019-02-11
diff --git a/third_party/blink/web_tests/css3/flexbox/fixedpos-video-in-abspos-quirk-crash.html b/third_party/blink/web_tests/css3/flexbox/fixedpos-video-in-abspos-quirk-crash.html
new file mode 100644
index 0000000..2f7e3f9
--- /dev/null
+++ b/third_party/blink/web_tests/css3/flexbox/fixedpos-video-in-abspos-quirk-crash.html
@@ -0,0 +1,11 @@
+<!-- Quirks mode needed -->
+<div style="position:absolute;">
+  <div>
+    <video style="position:fixed;"></video>
+  </div>
+</div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+  test(function() { }, "No crash or DCHECK failure");
+</script>
diff --git a/third_party/blink/web_tests/css3/flexbox/percentage-sizes-quirks.html b/third_party/blink/web_tests/css3/flexbox/percentage-sizes-quirks.html
index 4ebc25c..b169011 100644
--- a/third_party/blink/web_tests/css3/flexbox/percentage-sizes-quirks.html
+++ b/third_party/blink/web_tests/css3/flexbox/percentage-sizes-quirks.html
@@ -2,10 +2,10 @@
 .flexbox {
     display: flex;
 }
-.column {
+.column, .column .fixed {
     height: 50px;
 }
-.row {
+.row, .row .fixed {
     width: 50px;
 }
 .container > div {
@@ -13,6 +13,8 @@
 }
 .row > div > div {
     height: 20px;
+}
+.flexbox > div {
     flex: 0 0 auto;
 }
 .column > .flexbox {
@@ -37,8 +39,6 @@
 <body onload="checkLayout('.flexbox')">
 <div id=log></div>
 
-<div>CompatMode: <script>document.write(document.compatMode)</script></div>
-
 <div class="container row">
     <div class="flexbox">
         <div style='width: 10px; min-width: 50%;' data-expected-width=25></div>
@@ -48,8 +48,26 @@
     </div>
 </div>
 
-<div class="container column" style='margin-bottom: 50px'>
-    <div class="flexbox">
+<div class="container row" style='width: 100px'>
+    <div class="flexbox fixed">
+        <div style='width: 10px; min-width: 50%;' data-expected-width=25></div>
+        <div style='width: 50%;' data-expected-width=25></div>
+        <div style='width: 10px; max-width: 50%;' data-expected-width=10></div>
+        <div style='min-width: 10px; width: 100px; max-width: 50%;' data-expected-width=25></div>
+    </div>
+</div>
+
+<div class="container column" style='margin-bottom: 100px'>
+    <div class="flexbox" style="height: auto">
+        <div style='height: 10px; min-height: 50%;' data-expected-height=10></div>
+        <div style='height: 50%;' data-expected-height=0></div>
+        <div style='height: 10px; max-height: 50%;' data-expected-height=10></div>
+        <div style='min-height: 10px; height: 100px; max-height: 50%;' data-expected-height=100></div>
+    </div>
+</div>
+
+<div class="container column">
+    <div class="flexbox fixed">
         <div style='height: 10px; min-height: 50%;' data-expected-height=25></div>
         <div style='height: 50%;' data-expected-height=25></div>
         <div style='height: 10px; max-height: 50%;' data-expected-height=10></div>
@@ -65,6 +83,18 @@
 
 <div class="container column">
     <div class="flexbox">
+        <div style="flex: 0 0 50%" data-expected-height=0></div>
+    </div>
+</div>
+
+<div class="container row">
+    <div class="flexbox fixed">
+        <div style="flex: 0 0 50%" data-expected-width=25></div>
+    </div>
+</div>
+
+<div class="container column">
+    <div class="flexbox fixed">
         <div style="flex: 0 0 50%" data-expected-height=25></div>
     </div>
 </div>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index 32bc20d1..4ded385 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -44177,18 +44177,6 @@
      {}
     ]
    ],
-   "css/css-flexbox/percentage-heights-quirks-node.html": [
-    [
-     "/css/css-flexbox/percentage-heights-quirks-node.html",
-     [
-      [
-       "/css/reference/ref-filled-green-100px-square-only.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
    "css/css-flexbox/percentage-size-subitems-001.html": [
     [
      "/css/css-flexbox/percentage-size-subitems-001.html",
@@ -158233,16 +158221,6 @@
      {}
     ]
    ],
-   "encoding/encodeInto.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "encoding/encodeInto.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "encoding/eof-shift_jis-ref.html": [
     [
      {}
@@ -158263,26 +158241,6 @@
      {}
     ]
    ],
-   "encoding/idlharness.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "encoding/idlharness.any.serviceworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "encoding/idlharness.any.sharedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "encoding/idlharness.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "encoding/iso-2022-jp-decoder-expected.txt": [
     [
      {}
@@ -182743,6 +182701,11 @@
      {}
     ]
    ],
+   "screen-orientation/event-before-promise-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "screen-orientation/lock-basic-expected.txt": [
     [
      {}
@@ -210484,6 +210447,12 @@
      {}
     ]
    ],
+   "css/css-flexbox/quirks-auto-block-size-with-percentage-item.html": [
+    [
+     "/css/css-flexbox/quirks-auto-block-size-with-percentage-item.html",
+     {}
+    ]
+   ],
    "css/css-font-loading/fontfacesetloadevent-constructor.html": [
     [
      "/css/css-font-loading/fontfacesetloadevent-constructor.html",
@@ -276656,6 +276625,14 @@
      {}
     ]
    ],
+   "screen-orientation/event-before-promise.html": [
+    [
+     "/screen-orientation/event-before-promise.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "screen-orientation/idlharness.window.js": [
     [
      "/screen-orientation/idlharness.window.html",
@@ -339607,10 +339584,6 @@
    "5f3cfeec7e026ed3100c6af37ccc12ad9a5c5258",
    "reftest"
   ],
-  "css/css-flexbox/percentage-heights-quirks-node.html": [
-   "4b254b46467d6abff049090d5f37b1f3b3f6178e",
-   "reftest"
-  ],
   "css/css-flexbox/percentage-size-subitems-001.html": [
    "70f3953052a3a770c6cd15ee169607a00fc452b0",
    "reftest"
@@ -339647,6 +339620,10 @@
    "3199dfb9a699986ecbc7ff474628cf1cfbf0b0b6",
    "reftest"
   ],
+  "css/css-flexbox/quirks-auto-block-size-with-percentage-item.html": [
+   "966f39f173952f01268dcd26a9a5892bf4a689a9",
+   "testharness"
+  ],
   "css/css-flexbox/reference/Flexible-order-ref.html": [
    "12e94ba598e74cd253f0f91daf7e88f44884b7fc",
    "support"
@@ -393840,11 +393817,11 @@
    "support"
   ],
   "domparsing/XMLSerializer-serializeToString-expected.txt": [
-   "8729df1bec06a66ec792c0cbe940247f282a4ae1",
+   "965e6c1ab654444cf1dbae221c15d44644e7bfd1",
    "support"
   ],
   "domparsing/XMLSerializer-serializeToString.html": [
-   "d71da494fe7dbce56af5e45926739c7b6a232676",
+   "ab373481204e64070b8e3fd5a0f52f06211153b4",
    "testharness"
   ],
   "domparsing/createContextualFragment.html": [
@@ -394811,18 +394788,10 @@
    "7260b6b155b13de3961d170c3e2868042e229305",
    "testharness"
   ],
-  "encoding/encodeInto.any-expected.txt": [
-   "dd03ad6d4d8bf9b40a989e1b4edc28e192f06ba4",
-   "support"
-  ],
   "encoding/encodeInto.any.js": [
    "fda0d1b72ce787e940565575abb258012335269a",
    "testharness"
   ],
-  "encoding/encodeInto.any.worker-expected.txt": [
-   "dd03ad6d4d8bf9b40a989e1b4edc28e192f06ba4",
-   "support"
-  ],
   "encoding/eof-shift_jis-ref.html": [
    "b90f8032a31db260902c2c04b671b30ee9c62c8e",
    "support"
@@ -394863,26 +394832,10 @@
    "a6074f975d34fb6a216bdce4c7f560270512fd20",
    "testharness"
   ],
-  "encoding/idlharness.any-expected.txt": [
-   "8287d10c2fc1cfcb43aaa39d61ed52ba228cdb3c",
-   "support"
-  ],
   "encoding/idlharness.any.js": [
    "7a057f14e3a78c73b39a17f1debd3b8ad1e754d6",
    "testharness"
   ],
-  "encoding/idlharness.any.serviceworker-expected.txt": [
-   "8287d10c2fc1cfcb43aaa39d61ed52ba228cdb3c",
-   "support"
-  ],
-  "encoding/idlharness.any.sharedworker-expected.txt": [
-   "8287d10c2fc1cfcb43aaa39d61ed52ba228cdb3c",
-   "support"
-  ],
-  "encoding/idlharness.any.worker-expected.txt": [
-   "8287d10c2fc1cfcb43aaa39d61ed52ba228cdb3c",
-   "support"
-  ],
   "encoding/iso-2022-jp-decoder-expected.txt": [
    "e2530320ed21b50220eb6fc8eb0cb8b2c01b57e6",
    "support"
@@ -421668,7 +421621,7 @@
    "support"
   ],
   "interfaces/webxr.idl": [
-   "b1ed0f9072716efd5ef92ead32d58b396319dbfa",
+   "2bc100e100d89da510c56dc51d13d45335f67740",
    "support"
   ],
   "interfaces/worklets.idl": [
@@ -445575,6 +445528,14 @@
    "af79dee0418f0c92e44cc96352db9a5573bc2321",
    "support"
   ],
+  "screen-orientation/event-before-promise-expected.txt": [
+   "c22adc8ffc47ebaafaaec80faf3061bbf51b9883",
+   "support"
+  ],
+  "screen-orientation/event-before-promise.html": [
+   "d876b0c8873ebe0f009ebe4e6ef02a8bac52cf9c",
+   "testharness"
+  ],
   "screen-orientation/idlharness.window.js": [
    "115f6ccb1e393586f4076884c01443d4944bb413",
    "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/percentage-heights-quirks-node.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/percentage-heights-quirks-node.html
deleted file mode 100644
index 4b254b4..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/percentage-heights-quirks-node.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<title>In quirks mode a flex item should resolve its percentage height against its first ancestor with a defined height.</title>
-<link rel="help" href="https://quirks.spec.whatwg.org/#the-percentage-height-calculation-quirk">
-<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
-<p style="margin-top: 1em;">Test passes if there is a filled green square.</p>
-<div style="width: 200px; height: 200px;">
-  <div style="display: flex;">
-    <div style="width: 50%; height: 50%; background: green;"></div>
-  </div>
-</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/quirks-auto-block-size-with-percentage-item.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/quirks-auto-block-size-with-percentage-item.html
new file mode 100644
index 0000000..966f39f1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/quirks-auto-block-size-with-percentage-item.html
@@ -0,0 +1,17 @@
+<!-- quirks mode -->
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/CSS22/visudet.html#the-height-property">
+<meta name="assert" content="The percentage height resolution quirk isn't applied to flexboxes.">
+<p>There should be a green square to the left of a blue square, and no red.</p>
+<div id="container" style="width:200px; height:456px;">
+  <div style="display:flex; background:blue;" data-expected-height="100">
+    <img style="width:100px; height: 50%;" src="support/1x1-green.png" data-expected-height="100">
+    <div style="width: 50px; height: 100%; background: red;" data-expected-height="0"></div>
+  </div>
+</div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script>
+  checkLayout("#container");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-001.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-001.html
new file mode 100644
index 0000000..ebb93a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-001.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
+<meta name="assert" content="Checks that a replaced element, with an aspect ratio, converts a percent height into an intrinsic width." />
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<style>
+#float { float: left; height: 100px; background: green; }
+canvas { height: 100%; }
+</style>
+<p>Test passes if there is a filled green square.</p>
+<div id=float>
+  <canvas width=10 height=10></canvas>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-002.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-002.html
new file mode 100644
index 0000000..05051e6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-002.html
@@ -0,0 +1,14 @@
+<!-- quirks mode -->
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
+<meta name="assert" content="Checks that a replaced element, with an aspect ratio, converts a percent height into an intrinsic width." />
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<style>
+#float { float: left; height: 100px; background: green; }
+canvas { height: 100%; }
+</style>
+<p style="margin-top: 1em;">Test passes if there is a filled green square.</p>
+<div id=float>
+  <div>
+    <canvas width=10 height=10></canvas>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-003.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-003.html
new file mode 100644
index 0000000..0f130b8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-003.html
@@ -0,0 +1,17 @@
+<!-- quirks mode -->
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
+<meta name="assert" content="Checks that a replaced element, with an aspect ratio, converts a percent height into an intrinsic width." />
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<style>
+#container { height: 200px; }
+#float { float: left; height: 50%; background: green; }
+canvas { height: 100%; }
+</style>
+<p style="margin-top: 1em;">Test passes if there is a filled green square.</p>
+<div id=container>
+  <div id=float>
+    <div>
+      <canvas width=10 height=10></canvas>
+    </div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-004.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-004.html
new file mode 100644
index 0000000..1c4002b0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-004.html
@@ -0,0 +1,17 @@
+<!-- quirks mode -->
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
+<meta name="assert" content="Checks that a replaced element, with an aspect ratio, converts a percent height into an intrinsic width." />
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<style>
+#container { display: flex; height: 200px; }
+#float { float: left; height: 50%; background: green; }
+canvas { height: 100%; }
+</style>
+<p style="margin-top: 1em;">Test passes if there is a filled green square.</p>
+<div id=container>
+  <div id=float>
+    <div>
+      <canvas width=10 height=10></canvas>
+    </div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-005.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-005.html
new file mode 100644
index 0000000..84e945c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-005.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
+<meta name="assert" content="Checks that a replaced element, with an aspect ratio, converts a percent height into an intrinsic width." />
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<style>
+#container { position: relative; height: 100px; }
+#abs { position: absolute; top: 0; bottom: 0; background: green; }
+canvas { height: 100%; }
+</style>
+<p>Test passes if there is a filled green square.</p>
+<div id=container>
+  <div id=abs>
+    <canvas width=10 height=10></canvas>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-006.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-006.html
new file mode 100644
index 0000000..bce0a18
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/intrinsic-percent-replaced-006.html
@@ -0,0 +1,17 @@
+<!-- quirks mode -->
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
+<meta name="assert" content="Checks that a replaced element, with an aspect ratio, converts a percent height into an intrinsic width." />
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<style>
+#container { height: 100px; }
+#float { float: left; background: green; }
+canvas { height: 100%; }
+</style>
+<p style="margin-top: 1em;">Test passes if there is a filled green square.</p>
+<div id=container>
+  <div id=float>
+    <div>
+      <canvas width=10 height=10></canvas>
+    </div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
index b1ed0f9..2bc100e 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
@@ -3,6 +3,10 @@
 // (https://github.com/tidoust/reffy-reports)
 // Source: WebXR Device API (https://immersive-web.github.io/webxr/)
 
+partial interface Navigator {
+  [SecureContext, SameObject] readonly attribute XR xr;
+};
+
 [SecureContext, Exposed=Window] interface XR : EventTarget {
   // Methods
   Promise<void> supportsSessionMode(XRSessionMode mode);
@@ -12,11 +16,6 @@
   attribute EventHandler ondevicechange;
 };
 
-[SecureContext]
-partial interface Navigator {
-  [SameObject] readonly attribute XR xr;
-};
-
 enum XREnvironmentBlendMode {
   "opaque",
   "additive",
diff --git a/third_party/blink/web_tests/external/wpt/screen-orientation/event-before-promise-expected.txt b/third_party/blink/web_tests/external/wpt/screen-orientation/event-before-promise-expected.txt
new file mode 100644
index 0000000..c22adc8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/screen-orientation/event-before-promise-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL The 'change' event must fire before the [[orientationPendingPromise]] is resolved. assert_true: Expected an instance of Event expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/screen-orientation/event-before-promise.html b/third_party/blink/web_tests/external/wpt/screen-orientation/event-before-promise.html
new file mode 100644
index 0000000..d876b0c8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/screen-orientation/event-before-promise.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+  promise_test(async t => {
+    await test_driver.bless("request full screen", () => {
+      return document.documentElement.requestFullscreen();
+    });
+
+    const promiseToChange = new Promise(resolve => {
+      screen.orientation.addEventListener("change", resolve);
+    });
+
+    const result = await Promise.race([
+      screen.orientation.lock("landscape"),
+      promiseToChange
+    ]);
+
+    assert_true(result instanceof Event, "Expected an instance of Event");
+  }, "The 'change' event must fire before the [[orientationPendingPromise]] is resolved.");
+</script>
diff --git a/third_party/blink/web_tests/images/feature-policy-oversized-images-edge-cases-expected.txt b/third_party/blink/web_tests/images/feature-policy-oversized-images-edge-cases-expected.txt
new file mode 100644
index 0000000..8ce3e045
--- /dev/null
+++ b/third_party/blink/web_tests/images/feature-policy-oversized-images-edge-cases-expected.txt
@@ -0,0 +1 @@
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/images/feature-policy-oversized-images-expected.txt b/third_party/blink/web_tests/images/feature-policy-oversized-images-expected.txt
new file mode 100644
index 0000000..e9416b3
--- /dev/null
+++ b/third_party/blink/web_tests/images/feature-policy-oversized-images-expected.txt
@@ -0,0 +1,6 @@
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/images/feature-policy-oversized-images-forced-layout-expected.txt b/third_party/blink/web_tests/images/feature-policy-oversized-images-forced-layout-expected.txt
new file mode 100644
index 0000000..bc6ee3552
--- /dev/null
+++ b/third_party/blink/web_tests/images/feature-policy-oversized-images-forced-layout-expected.txt
@@ -0,0 +1,2 @@
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/images/feature-policy-oversized-images-resize-expected.txt b/third_party/blink/web_tests/images/feature-policy-oversized-images-resize-expected.txt
new file mode 100644
index 0000000..c8ca17d
--- /dev/null
+++ b/third_party/blink/web_tests/images/feature-policy-oversized-images-resize-expected.txt
@@ -0,0 +1,4 @@
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/images/feature-policy-oversized-images-responsive-image-expected.txt b/third_party/blink/web_tests/images/feature-policy-oversized-images-responsive-image-expected.txt
new file mode 100644
index 0000000..bc6ee3552
--- /dev/null
+++ b/third_party/blink/web_tests/images/feature-policy-oversized-images-responsive-image-expected.txt
@@ -0,0 +1,2 @@
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/images/feature-policy-oversized-images-styles-expected.txt b/third_party/blink/web_tests/images/feature-policy-oversized-images-styles-expected.txt
new file mode 100644
index 0000000..40a04856
--- /dev/null
+++ b/third_party/blink/web_tests/images/feature-policy-oversized-images-styles-expected.txt
@@ -0,0 +1,3 @@
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
+CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/feed/README.chromium b/third_party/feed/README.chromium
index 338f3980..dd85354e 100644
--- a/third_party/feed/README.chromium
+++ b/third_party/feed/README.chromium
@@ -2,7 +2,7 @@
 Short name: feed
 URL: https://chromium.googlesource.com/feed
 Version: 0
-Revision: 159a13d840ef3638205987e117f746fb12514edf
+Revision: 3293f23ae831c666be27273fbf2a73d9b2fe7552
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/third_party/flatbuffers/BUILD.gn b/third_party/flatbuffers/BUILD.gn
index 87c4ca20..03f5652 100644
--- a/third_party/flatbuffers/BUILD.gn
+++ b/third_party/flatbuffers/BUILD.gn
@@ -7,10 +7,6 @@
 
 config("flatbuffers_config") {
   include_dirs = [ "src/include" ]
-
-  if (is_clang) {
-    cflags = [ "-Wno-exit-time-destructors" ]
-  }
 }
 
 # The part of FlatBuffers that Chrome is interested in.
diff --git a/third_party/polymer/v1_0/bower.json b/third_party/polymer/v1_0/bower.json
index 9a4fbe240..cab6cc0 100644
--- a/third_party/polymer/v1_0/bower.json
+++ b/third_party/polymer/v1_0/bower.json
@@ -3,6 +3,7 @@
   "private": true,
   "dependencies": {
     "font-roboto": "PolymerElements/font-roboto#1.0.1",
+    "html-imports": "webcomponents/html-imports#1.2.0",
     "iron-a11y-announcer": "PolymerElements/iron-a11y-announcer#2.1.0",
     "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#2.1.1",
     "iron-a11y-keys": "PolymerElements/iron-a11y-keys#2.0.0",
diff --git a/third_party/polymer/v1_0/chromium.patch b/third_party/polymer/v1_0/chromium.patch
index bcdd3e4..6102949 100644
--- a/third_party/polymer/v1_0/chromium.patch
+++ b/third_party/polymer/v1_0/chromium.patch
@@ -9,6 +9,16 @@
 -<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic">
 -<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700">
 +<link rel="stylesheet" href="chrome://resources/css/roboto.css">
+diff --git a/components-chromium/html-imports/html-imports.min.js b/components-chromium/html-imports/html-imports.min.js
+index 3365917e8b99..8750aefdefb1 100644
+--- a/components-chromium/html-imports/html-imports.min.js
++++ b/components-chromium/html-imports/html-imports.min.js
+@@ -23,5 +23,3 @@ if(d&&b.parentNode!==document.head){var e=document.createElement(b.localName);e.
+ "complete"),a.dispatchEvent(y(a.import?"load":"error",{bubbles:!1,cancelable:!1,detail:void 0})))};h.prototype.w=function(a){var b=this;g(a,function(a){return g(a.addedNodes,function(a){a&&a.nodeType===Node.ELEMENT_NODE&&(r(a)?b.l(a):b.loadImports(a))})})};var x=null;if(u)g(k(document,"link[rel=import]"),function(a){a.import&&"loading"===a.import.readyState||(a.__loaded=!0)}),n=function(a){a=a.target;r(a)&&(a.__loaded=!0)},document.addEventListener("load",n,!0),document.addEventListener("error",n,
+ !0);else{var p=Object.getOwnPropertyDescriptor(Node.prototype,"baseURI");Object.defineProperty((!p||p.configurable?Node:Element).prototype,"baseURI",{get:function(){var a=r(this)?this:m(this);return a?a.href:p&&p.get?p.get.call(this):(document.querySelector("base")||window.location).href},configurable:!0,enumerable:!0});Object.defineProperty(HTMLLinkElement.prototype,"import",{get:function(){return this.__import||null},configurable:!0,enumerable:!0});z(function(){x=new h})}A(function(){return document.dispatchEvent(y("HTMLImportsLoaded",
+ {cancelable:!0,bubbles:!0,detail:void 0}))});q.useNative=u;q.whenReady=A;q.importForElement=m;q.loadImports=function(a){x&&x.loadImports(a)}})(window.HTMLImports=window.HTMLImports||{});
+-
+-//# sourceMappingURL=html-imports.min.js.map
 diff --git a/components-chromium/iron-iconset-svg/iron-iconset-svg-extracted.js b/components-chromium/iron-iconset-svg/iron-iconset-svg-extracted.js
 index 2edddb115d46..d3c7fbe36d63 100644
 --- a/components-chromium/iron-iconset-svg/iron-iconset-svg-extracted.js
diff --git a/third_party/polymer/v1_0/components-chromium/html-imports/bower.json b/third_party/polymer/v1_0/components-chromium/html-imports/bower.json
new file mode 100644
index 0000000..7363d32
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/html-imports/bower.json
@@ -0,0 +1,31 @@
+{
+  "name": "html-imports",
+  "main": "html-imports.min.js",
+  "description": "HTML Imports polyfill",
+  "homepage": "https://webcomponents.org/polyfills",
+  "authors": [
+    "The Polymer Authors (https://polymer.github.io/AUTHORS.txt)"
+  ],
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/webcomponents/html-imports.git"
+  },
+  "keywords": [
+    "html-imports",
+    "htmlimports",
+    "web-components",
+    "webcomponents",
+    "polyfill",
+    "shim"
+  ],
+  "license": "BSD-3-Clause",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components"
+  ],
+  "devDependencies": {
+    "template": "webcomponents/template#^1.2.1",
+    "web-component-tester": "^6.4.1"
+  }
+}
diff --git a/third_party/polymer/v1_0/components-chromium/html-imports/html-imports.min.js b/third_party/polymer/v1_0/components-chromium/html-imports/html-imports.min.js
new file mode 100644
index 0000000..8750aef
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/html-imports/html-imports.min.js
@@ -0,0 +1,25 @@
+/*
+
+ Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+'use strict';(function(q){function y(a,b){if("function"===typeof window.CustomEvent)return new CustomEvent(a,b);var c=document.createEvent("CustomEvent");c.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail);return c}function m(a){if(u)return a.ownerDocument!==document?a.ownerDocument:null;var b=a.__importDoc;if(!b&&a.parentNode){b=a.parentNode;if("function"===typeof b.closest)b=b.closest("link[rel=import]");else for(;!r(b)&&(b=b.parentNode););a.__importDoc=b}return b}function D(a){var b=k(document,
+"link[rel=import]:not([import-dependency])"),c=b.length;c?g(b,function(b){return t(b,function(){0===--c&&a()})}):a()}function z(a){function b(){"loading"!==document.readyState&&document.body&&(document.removeEventListener("readystatechange",b),a())}document.addEventListener("readystatechange",b);b()}function A(a){z(function(){return D(function(){return a&&a()})})}function t(a,b){if(a.__loaded)b&&b();else if("script"===a.localName&&!a.src||"style"===a.localName&&!a.firstChild)a.__loaded=!0,b&&b();
+else{var c=function(d){a.removeEventListener(d.type,c);a.__loaded=!0;b&&b()};a.addEventListener("load",c);v&&"style"===a.localName||a.addEventListener("error",c)}}function r(a){return a.nodeType===Node.ELEMENT_NODE&&"link"===a.localName&&"import"===a.rel}function h(){var a=this;this.a={};this.b=0;this.g=new MutationObserver(function(b){return a.w(b)});this.g.observe(document.head,{childList:!0,subtree:!0});this.loadImports(document)}function B(a){g(k(a,"template"),function(a){g(k(a.content,'script:not([type]),script[type="application/javascript"],script[type="text/javascript"],script[type="module"]'),
+function(a){var b=document.createElement("script");g(a.attributes,function(a){return b.setAttribute(a.name,a.value)});b.textContent=a.textContent;a.parentNode.replaceChild(b,a)});B(a.content)})}function k(a,b){return a.childNodes.length?a.querySelectorAll(b):E}function g(a,b,c){var d=a?a.length:0,f=c?-1:1;for(c=c?d-1:0;c<d&&0<=c;c+=f)b(a[c],c)}var n=document.createElement("link"),u="import"in n,E=n.querySelectorAll("*"),w=null;!1==="currentScript"in document&&Object.defineProperty(document,"currentScript",
+{get:function(){return w||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null)},configurable:!0});var F=/(url\()([^)]*)(\))/g,G=/(@import[\s]+(?!url\())([^;]*)(;)/g,H=/(<link[^>]*)(rel=['|"]?stylesheet['|"]?[^>]*>)/g,e={u:function(a,b){a.href&&a.setAttribute("href",e.c(a.getAttribute("href"),b));a.src&&a.setAttribute("src",e.c(a.getAttribute("src"),b));if("style"===a.localName){var c=e.o(a.textContent,b,F);a.textContent=e.o(c,b,G)}},o:function(a,b,c){return a.replace(c,
+function(a,c,l,g){a=l.replace(/["']/g,"");b&&(a=e.c(a,b));return c+"'"+a+"'"+g})},c:function(a,b){if(void 0===e.f){e.f=!1;try{var c=new URL("b","http://a");c.pathname="c%20d";e.f="http://a/c%20d"===c.href}catch(d){}}if(e.f)return(new URL(a,b)).href;c=e.s;c||(c=document.implementation.createHTMLDocument("temp"),e.s=c,c.i=c.createElement("base"),c.head.appendChild(c.i),c.h=c.createElement("a"));c.i.href=b;c.h.href=a;return c.h.href||a}},C={async:!0,load:function(a,b,c){if(a)if(a.match(/^data:/)){a=
+a.split(",");var d=a[1];d=-1<a[0].indexOf(";base64")?atob(d):decodeURIComponent(d);b(d)}else{var f=new XMLHttpRequest;f.open("GET",a,C.async);f.onload=function(){var a=f.responseURL||f.getResponseHeader("Location");a&&0===a.indexOf("/")&&(a=(location.origin||location.protocol+"//"+location.host)+a);var d=f.response||f.responseText;304===f.status||0===f.status||200<=f.status&&300>f.status?b(d,a):c(d)};f.send()}else c("error: href must be specified")}},v=/Trident/.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent);
+h.prototype.loadImports=function(a){var b=this;g(k(a,"link[rel=import]"),function(a){return b.l(a)})};h.prototype.l=function(a){var b=this,c=a.href;if(void 0!==this.a[c]){var d=this.a[c];d&&d.__loaded&&(a.__import=d,this.j(a))}else this.b++,this.a[c]="pending",C.load(c,function(a,d){a=b.A(a,d||c);b.a[c]=a;b.b--;b.loadImports(a);b.m()},function(){b.a[c]=null;b.b--;b.m()})};h.prototype.A=function(a,b){if(!a)return document.createDocumentFragment();v&&(a=a.replace(H,function(a,b,c){return-1===a.indexOf("type=")?
+b+" type=import-disable "+c:a}));var c=document.createElement("template");c.innerHTML=a;if(c.content)a=c.content,B(a);else for(a=document.createDocumentFragment();c.firstChild;)a.appendChild(c.firstChild);if(c=a.querySelector("base"))b=e.c(c.getAttribute("href"),b),c.removeAttribute("href");var d=0;g(k(a,'link[rel=import],link[rel=stylesheet][href][type=import-disable],style:not([type]),link[rel=stylesheet][href]:not([type]),script:not([type]),script[type="application/javascript"],script[type="text/javascript"],script[type="module"]'),
+function(a){t(a);e.u(a,b);a.setAttribute("import-dependency","");if("script"===a.localName&&!a.src&&a.textContent){if("module"===a.type)throw Error("Inline module scripts are not supported in HTML Imports.");a.setAttribute("src","data:text/javascript;charset=utf-8,"+encodeURIComponent(a.textContent+("\n//# sourceURL="+b+(d?"-"+d:"")+".js\n")));a.textContent="";d++}});return a};h.prototype.m=function(){var a=this;if(!this.b){this.g.disconnect();this.flatten(document);var b=!1,c=!1,d=function(){c&&
+b&&(a.loadImports(document),a.b||(a.g.observe(document.head,{childList:!0,subtree:!0}),a.v()))};this.C(function(){c=!0;d()});this.B(function(){b=!0;d()})}};h.prototype.flatten=function(a){var b=this;g(k(a,"link[rel=import]"),function(a){var c=b.a[a.href];(a.__import=c)&&c.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(b.a[a.href]=a,a.readyState="loading",a.__import=a,b.flatten(c),a.appendChild(c))})};h.prototype.B=function(a){function b(f){if(f<d){var l=c[f],e=document.createElement("script");l.removeAttribute("import-dependency");
+g(l.attributes,function(a){return e.setAttribute(a.name,a.value)});w=e;l.parentNode.replaceChild(e,l);t(e,function(){w=null;b(f+1)})}else a()}var c=k(document,"script[import-dependency]"),d=c.length;b(0)};h.prototype.C=function(a){var b=k(document,"style[import-dependency],link[rel=stylesheet][import-dependency]"),c=b.length;if(c){var d=v&&!!document.querySelector("link[rel=stylesheet][href][type=import-disable]");g(b,function(b){t(b,function(){b.removeAttribute("import-dependency");0===--c&&a()});
+if(d&&b.parentNode!==document.head){var e=document.createElement(b.localName);e.__appliedElement=b;e.setAttribute("type","import-placeholder");b.parentNode.insertBefore(e,b.nextSibling);for(e=m(b);e&&m(e);)e=m(e);e.parentNode!==document.head&&(e=null);document.head.insertBefore(b,e);b.removeAttribute("type")}})}else a()};h.prototype.v=function(){var a=this;g(k(document,"link[rel=import]"),function(b){return a.j(b)},!0)};h.prototype.j=function(a){a.__loaded||(a.__loaded=!0,a.import&&(a.import.readyState=
+"complete"),a.dispatchEvent(y(a.import?"load":"error",{bubbles:!1,cancelable:!1,detail:void 0})))};h.prototype.w=function(a){var b=this;g(a,function(a){return g(a.addedNodes,function(a){a&&a.nodeType===Node.ELEMENT_NODE&&(r(a)?b.l(a):b.loadImports(a))})})};var x=null;if(u)g(k(document,"link[rel=import]"),function(a){a.import&&"loading"===a.import.readyState||(a.__loaded=!0)}),n=function(a){a=a.target;r(a)&&(a.__loaded=!0)},document.addEventListener("load",n,!0),document.addEventListener("error",n,
+!0);else{var p=Object.getOwnPropertyDescriptor(Node.prototype,"baseURI");Object.defineProperty((!p||p.configurable?Node:Element).prototype,"baseURI",{get:function(){var a=r(this)?this:m(this);return a?a.href:p&&p.get?p.get.call(this):(document.querySelector("base")||window.location).href},configurable:!0,enumerable:!0});Object.defineProperty(HTMLLinkElement.prototype,"import",{get:function(){return this.__import||null},configurable:!0,enumerable:!0});z(function(){x=new h})}A(function(){return document.dispatchEvent(y("HTMLImportsLoaded",
+{cancelable:!0,bubbles:!0,detail:void 0}))});q.useNative=u;q.whenReady=A;q.importForElement=m;q.loadImports=function(a){x&&x.loadImports(a)}})(window.HTMLImports=window.HTMLImports||{});
diff --git a/third_party/polymer/v1_0/components_summary.txt b/third_party/polymer/v1_0/components_summary.txt
index 161a74e9..716aff4a 100644
--- a/third_party/polymer/v1_0/components_summary.txt
+++ b/third_party/polymer/v1_0/components_summary.txt
@@ -4,6 +4,12 @@
 Revision: 21ce9b51a417fa9995cf6606e886aba0728f70a1
 Tree link: https://github.com/PolymerElements/font-roboto/tree/v1.0.1
 
+Name: html-imports
+Repository: https://github.com/webcomponents/html-imports.git
+Tree: v1.2.0
+Revision: bcdbb81201faad37270b03f59a29f2f27cb70312
+Tree link: https://github.com/webcomponents/html-imports/tree/v1.2.0
+
 Name: iron-a11y-announcer
 Repository: https://github.com/PolymerElements/iron-a11y-announcer.git
 Tree: v2.1.0
diff --git a/third_party/polymer/v1_0/find_unused_elements.py b/third_party/polymer/v1_0/find_unused_elements.py
index 1ec5e164..3a8aae0 100644
--- a/third_party/polymer/v1_0/find_unused_elements.py
+++ b/third_party/polymer/v1_0/find_unused_elements.py
@@ -29,6 +29,8 @@
     # Not used yet. Will be used as part of Polymer 2 migration.
     'polymer2',
     'shadycss',
+    # Not used yet. Will be used when pages are moved off of HTML imports.
+    'html-imports',
   )
 
   def __init__(self):
diff --git a/tools/clang/pylib/clang/PRESUBMIT.py b/tools/clang/pylib/clang/PRESUBMIT.py
index 0ca7653..35eae77 100644
--- a/tools/clang/pylib/clang/PRESUBMIT.py
+++ b/tools/clang/pylib/clang/PRESUBMIT.py
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 
-def _CommonChecks(input_api, output_api):
+def CheckChangeOnCommit(input_api, output_api):
   results = []
 
   # Run the unit tests.
@@ -11,11 +11,3 @@
       input_api, output_api, '.', [ r'^.+_test\.py$']))
 
   return results
-
-
-def CheckChangeOnUpload(input_api, output_api):
-  return _CommonChecks(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
-  return _CommonChecks(input_api, output_api)
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 34369c27..cdd1027 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -1972,6 +1972,13 @@
   </description>
 </action>
 
+<action name="Android.LaunchNewIncognitoTab">
+  <owner>peconn@chromium.org</owner>
+  <description>
+    An external application launched a new Chrome Incognito Tab.
+  </description>
+</action>
+
 <action name="Android.ManageSpace">
   <owner>dmurph@chromium.org</owner>
   <description>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv
index f734db9..65078c9 100644
--- a/tools/perf/benchmark.csv
+++ b/tools/perf/benchmark.csv
@@ -56,16 +56,16 @@
 speedometer2-future,hablich@chromium.org,Blink,,
 startup.mobile,"pasko@chromium.org, chrome-android-perf-status@chromium.org",Speed>Metrics>SystemHealthRegressions,,
 supersize_archive,agrieve@chromium.org,,,
-system_health.common_desktop,"charliea@chromium.org, sullivan@chromium.org, tdresser@chromium.org, chrome-speed-metrics-dev@chromium.org",Speed>Metrics>SystemHealthRegressions,https://bit.ly/system-health-benchmarks,"2016,2018,accessibility,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,scroll,tabs_switching,webgl"
+system_health.common_desktop,"charliea@chromium.org, sullivan@chromium.org, tdresser@chromium.org, chrome-speed-metrics-dev@chromium.org",Speed>Metrics>SystemHealthRegressions,https://bit.ly/system-health-benchmarks,"2016,2018,2019,accessibility,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,scroll,tabs_switching,webgl"
 system_health.common_mobile,"charliea@chromium.org, sullivan@chromium.org, tdresser@chromium.org, perezju@chromium.org, chrome-speed-metrics-dev@chromium.org",Speed>Metrics>SystemHealthRegressions,https://bit.ly/system-health-benchmarks,"2016,2018,2019,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy"
-system_health.memory_desktop,perezju@chromium.org,,https://bit.ly/system-health-benchmarks,"2016,2018,accessibility,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,scroll,tabs_switching,webgl"
+system_health.memory_desktop,perezju@chromium.org,,https://bit.ly/system-health-benchmarks,"2016,2018,2019,accessibility,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,scroll,tabs_switching,webgl"
 system_health.memory_mobile,perezju@chromium.org,,https://bit.ly/system-health-benchmarks,"2016,2018,2019,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy"
 system_health.webview_startup,"perezju@chromium.org, torne@chromium.org, changwan@chromium.org",Mobile>WebView>Perf,,"2016,health_check"
 tab_switching.typical_25,vovoy@chromium.org,OS>Performance,,"2016,tabs_switching"
 tracing.tracing_with_background_memory_infra,ssid@chromium.org,,,
 tracing_perftests,"kkraynov@chromium.org, primiano@chromium.org",,,
-v8.browsing_desktop,"mythria@chromium.org, ulan@chromium.org",Blink>JavaScript,,"2016,2018,health_check,images,infinite_scroll,international,javascript_heavy,webgl"
-v8.browsing_desktop-future,"mythria@chromium.org, ulan@chromium.org",Blink>JavaScript,,"2016,2018,health_check,images,infinite_scroll,international,javascript_heavy,webgl"
+v8.browsing_desktop,"mythria@chromium.org, ulan@chromium.org",Blink>JavaScript,,"2016,2018,2019,health_check,images,infinite_scroll,international,javascript_heavy,webgl"
+v8.browsing_desktop-future,"mythria@chromium.org, ulan@chromium.org",Blink>JavaScript,,"2016,2018,2019,health_check,images,infinite_scroll,international,javascript_heavy,webgl"
 v8.browsing_mobile,"mythria@chromium.org, ulan@chromium.org",Blink>JavaScript,,"2016,2018,2019,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy"
 v8.browsing_mobile-future,"mythria@chromium.org, ulan@chromium.org",Blink>JavaScript,,"2016,2018,2019,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy"
 v8.runtime_stats.top_25,"cbruni@chromium.org, mythria@chromium.org",Blink>JavaScript,,"cold,hot,warm"
diff --git a/tools/perf/contrib/network_service/loading.py b/tools/perf/contrib/network_service/loading.py
index aa9186b..ed5f416f 100644
--- a/tools/perf/contrib/network_service/loading.py
+++ b/tools/perf/contrib/network_service/loading.py
@@ -83,7 +83,6 @@
     if chart_name == 'trace':
       continue
     chart = charts[chart_name]
-    chart_name = chart_name.split('@@', 1)[-1]
     new_chart_name = chart_name + suffix
     for point_name in chart:
       chart[point_name]['name'] = new_chart_name
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 90d9bfb..458b1a3 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -260,6 +260,7 @@
 crbug.com/923106 [ Linux ] system_health.common_desktop/browse:media:tumblr [ Skip ]
 crbug.com/923106 [ Win ] system_health.common_desktop/browse:media:tumblr [ Skip ]
 crbug.com/927758 [ Desktop ] system_health.common_desktop/load:games:alphabetty [ Skip ]
+crbug.com/931185 [ Win_7 ] system_health.common_desktop/browse:media:youtubetv:2019 [ Skip ]
 
 # Benchmark: system_health.common_mobile
 crbug.com/914390 [ Nexus_5 ] system_health.common_mobile/browse:chrome:newtab [ Skip ]
diff --git a/tools/perf/page_sets/data/system_health_desktop.json b/tools/perf/page_sets/data/system_health_desktop.json
index 194de6c7..f6d79f7 100644
--- a/tools/perf/page_sets/data/system_health_desktop.json
+++ b/tools/perf/page_sets/data/system_health_desktop.json
@@ -30,6 +30,9 @@
         "browse:media:youtube:2018": {
             "DEFAULT": "system_health_desktop_6b6bdda708.wprgo"
         },
+        "browse:media:youtubetv:2019": {
+            "DEFAULT": "system_health_desktop_e53598d1f4.wprgo"
+        },
         "browse:news:cnn": {
             "DEFAULT": "system_health_desktop_013.wprgo"
         },
diff --git a/tools/perf/page_sets/data/system_health_desktop_e53598d1f4.wprgo.sha1 b/tools/perf/page_sets/data/system_health_desktop_e53598d1f4.wprgo.sha1
new file mode 100644
index 0000000..0495761
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_desktop_e53598d1f4.wprgo.sha1
@@ -0,0 +1 @@
+e53598d1f4557890bb40bd9a469c075709f44043
\ No newline at end of file
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py
index ec48ddf..c91e49a 100644
--- a/tools/perf/page_sets/system_health/browsing_stories.py
+++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -645,6 +645,85 @@
           '--enable-blink-features=HTMLImports,CustomElementsV0'])
 
 
+class YouTubeTVDesktopStory2019(_MediaBrowsingStory):
+  """Load a typical YouTube TV video then navigate to a next few videos. Stop
+  and watch each video for a few seconds.
+  """
+  NAME = 'browse:media:youtubetv:2019'
+  URL = 'https://www.youtube.com/tv#/watch/ads/control?v=PxrnoGyBw4E&resume'
+  SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
+  TAGS = [story_tags.YEAR_2019]
+
+  def WaitIfRecording(self, action_runner):
+    # Uncomment the below if recording to try and reduce network errors.
+    # action_runner.Wait(2)
+    pass
+
+  def WatchThenSkipAd(self, action_runner):
+    skip_button_selector = '.skip-ad-button'
+    action_runner.WaitForElement(selector=skip_button_selector)
+    action_runner.Wait(8)  # Wait until the ad is skippable.
+    action_runner.MouseClick(selector=skip_button_selector)
+    self.WaitIfRecording(action_runner)
+
+  def ShortAttentionSpan(self, action_runner):
+    action_runner.Wait(2)
+
+  def GotoNextVideo(self, action_runner):
+    forward_button_selector = '.skip-forward-button'
+    action_runner.PressKey('ArrowDown')   # Open the menu.
+    action_runner.WaitForElement(selector=forward_button_selector)
+    action_runner.MouseClick(selector=forward_button_selector)
+    self.WaitIfRecording(action_runner)
+
+  def NavigateInMenu(self, action_runner):
+    short_delay_in_ms = 300
+    delay_in_ms = 1000
+    long_delay_in_ms = 3000
+    # Escape to menu, skip the sign-in process.
+    action_runner.PressKey('Backspace', 1, long_delay_in_ms)
+    action_runner.PressKey('ArrowDown', 1, delay_in_ms)
+    action_runner.PressKey('Return', 1, long_delay_in_ms)
+    self.WaitIfRecording(action_runner)
+    # Scroll through categories and back.
+    action_runner.WaitForElement(selector='#guide-logo')
+    action_runner.PressKey('ArrowUp', 1, delay_in_ms)
+    action_runner.PressKey('ArrowRight', 3, delay_in_ms)
+    action_runner.PressKey('ArrowLeft', 3, delay_in_ms)
+    action_runner.PressKey('ArrowDown', 1, delay_in_ms)
+    self.WaitIfRecording(action_runner)
+    # Scroll through a few videos then open the sidebar menu.
+    action_runner.PressKey('ArrowRight', 3, short_delay_in_ms)
+    action_runner.PressKey('ArrowDown', 3, short_delay_in_ms)
+    action_runner.PressKey('Backspace', 2, delay_in_ms)
+    self.WaitIfRecording(action_runner)
+    # Scroll through options and then go to search.
+    action_runner.PressKey('ArrowDown', 3, delay_in_ms)
+    action_runner.PressKey('s', 1, delay_in_ms)
+    self.WaitIfRecording(action_runner)
+    # Search for 'dub stories' and start playing.
+    action_runner.EnterText('dub stories', short_delay_in_ms)
+    action_runner.PressKey('ArrowDown', 1, delay_in_ms)
+    action_runner.PressKey('Return', 2, delay_in_ms)
+    self.WaitIfRecording(action_runner)
+
+  def _DidLoadDocument(self, action_runner):
+    self.WatchThenSkipAd(action_runner)
+    self.ShortAttentionSpan(action_runner)
+    self.GotoNextVideo(action_runner)
+    self.ShortAttentionSpan(action_runner)
+    self.GotoNextVideo(action_runner)
+    self.ShortAttentionSpan(action_runner)
+    self.NavigateInMenu(action_runner)
+
+  # This story is mainly relevant for V8 in jitless mode, but there is no
+  # benchmark that enables this flag. We take the pragmatic solution and set
+  # this flag explicitly for this story.
+  def __init__(self, story_set, take_memory_measurement):
+    super(YouTubeTVDesktopStory2019, self).__init__(
+        story_set, take_memory_measurement,
+        extra_browser_args=['--js-flags="--jitless"'])
+
 class FacebookPhotosMobileStory(_MediaBrowsingStory):
   """Load a photo page from Rihanna's facebook page then navigate a few next
   photos.
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index f378c3b..2395f408 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -53,7 +53,7 @@
  <item id="cloud_print_privet_register" hash_code="24978481" type="0" content_hash_code="131359002" os_list="linux,windows" file_path="chrome/browser/printing/cloud_print/gcd_api_flow_impl.cc"/>
  <item id="cloud_print_proxy" hash_code="50859288" type="1" second_id="111712433" content_hash_code="90868083" os_list="linux,windows" semantics_fields="2,3,4" file_path="chrome/service/cloud_print/cloud_print_proxy.cc"/>
  <item id="cloud_print_search" hash_code="132055347" type="0" content_hash_code="123783474" os_list="linux,windows" file_path="chrome/browser/printing/cloud_print/gcd_api_flow_impl.cc"/>
- <item id="component_updater_utils" hash_code="125596241" type="0" content_hash_code="12311195" os_list="linux,windows" file_path="components/update_client/utils.cc"/>
+ <item id="component_updater_utils" hash_code="125596241" type="0" content_hash_code="12311195" os_list="linux,windows" file_path="components/update_client/network.cc"/>
  <item id="content_hash_verification_job" hash_code="64733114" type="0" content_hash_code="127912411" os_list="linux,windows" file_path="extensions/browser/content_hash_fetcher.cc"/>
  <item id="content_resource_fetcher" hash_code="70796791" type="0" deprecated="2017-09-16" content_hash_code="135648626" file_path=""/>
  <item id="content_suggestion_get_favicon" hash_code="16653985" type="0" content_hash_code="134280933" os_list="linux,windows" file_path="components/ntp_snippets/content_suggestions_service.cc"/>
@@ -276,7 +276,7 @@
  <item id="ui_devtools_server" hash_code="4986170" type="0" content_hash_code="62670263" os_list="linux,windows" file_path="components/ui_devtools/devtools_server.cc"/>
  <item id="undefined" hash_code="45578882" type="0" reserved="1" os_list="linux,windows" file_path=""/>
  <item id="unwanted_software_report" hash_code="43759504" type="0" content_hash_code="43217092" os_list="windows" file_path="chrome/chrome_cleaner/logging/reporter_logging_service.cc"/>
- <item id="url_fetcher_downloader" hash_code="113231892" type="0" content_hash_code="61085066" os_list="linux,windows" file_path="components/update_client/url_fetcher_downloader.cc"/>
+ <item id="url_fetcher_downloader" hash_code="113231892" type="0" deprecated="2019-02-09" content_hash_code="61085066" file_path=""/>
  <item id="url_prevision_fetcher" hash_code="118389509" type="0" content_hash_code="66145513" os_list="linux,windows" file_path="content/browser/media/url_provision_fetcher.cc"/>
  <item id="user_info_fetcher" hash_code="22265491" type="0" content_hash_code="72016232" os_list="linux,windows" file_path="components/policy/core/common/cloud/user_info_fetcher.cc"/>
  <item id="viz_devtools_server" hash_code="16292315" type="0" content_hash_code="70061664" os_list="linux,windows" file_path="components/ui_devtools/devtools_server.cc"/>
diff --git a/ui/file_manager/audio_player/elements/audio_player.js b/ui/file_manager/audio_player/elements/audio_player.js
index 68a352f..ae96d3e 100644
--- a/ui/file_manager/audio_player/elements/audio_player.js
+++ b/ui/file_manager/audio_player/elements/audio_player.js
@@ -218,6 +218,7 @@
     if(this.repeatMode === "repeat-one") {
       this.playing = true;
       this.$.audio.currentTime = 0;
+      this.time = 0;
       return;
     }
     this.advance_(true /* forward */, this.repeatMode === "repeat-all");
@@ -290,6 +291,7 @@
     var shouldFireEvent = this.$.trackList.currentTrackIndex === nextTrackIndex;
     this.$.trackList.currentTrackIndex = nextTrackIndex;
     this.$.audio.currentTime = 0;
+    this.time = 0;
     // If the next track and current track is the same,
     // the event will not be fired.
     // So we will fire the event here.
diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn
index 82bb136..db02f4b 100644
--- a/ui/ozone/platform/drm/BUILD.gn
+++ b/ui/ozone/platform/drm/BUILD.gn
@@ -20,6 +20,10 @@
     "client_native_pixmap_factory_gbm.cc",
     "client_native_pixmap_factory_gbm.h",
     "common/display_types.h",
+    "common/drm_overlay_candidates.cc",
+    "common/drm_overlay_candidates.h",
+    "common/drm_overlay_manager.cc",
+    "common/drm_overlay_manager.h",
     "common/drm_util.cc",
     "common/drm_util.h",
     "common/scoped_drm_types.cc",
@@ -100,10 +104,8 @@
     "host/drm_gpu_platform_support_host.h",
     "host/drm_native_display_delegate.cc",
     "host/drm_native_display_delegate.h",
-    "host/drm_overlay_candidates_host.cc",
-    "host/drm_overlay_candidates_host.h",
-    "host/drm_overlay_manager.cc",
-    "host/drm_overlay_manager.h",
+    "host/drm_overlay_manager_host.cc",
+    "host/drm_overlay_manager_host.h",
     "host/drm_window_host.cc",
     "host/drm_window_host.h",
     "host/drm_window_host_manager.cc",
diff --git a/ui/ozone/platform/drm/common/drm_overlay_candidates.cc b/ui/ozone/platform/drm/common/drm_overlay_candidates.cc
new file mode 100644
index 0000000..97b0deed
--- /dev/null
+++ b/ui/ozone/platform/drm/common/drm_overlay_candidates.cc
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/drm/common/drm_overlay_candidates.h"
+
+#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
+#include "ui/ozone/public/overlay_surface_candidate.h"
+
+namespace ui {
+
+DrmOverlayCandidates::DrmOverlayCandidates(DrmOverlayManager* manager,
+                                           gfx::AcceleratedWidget widget)
+    : overlay_manager_(manager), widget_(widget) {}
+
+DrmOverlayCandidates::~DrmOverlayCandidates() = default;
+
+void DrmOverlayCandidates::CheckOverlaySupport(
+    std::vector<OverlaySurfaceCandidate>* candidates) {
+  overlay_manager_->CheckOverlaySupport(candidates, widget_);
+}
+
+}  // namespace ui
diff --git a/ui/ozone/platform/drm/common/drm_overlay_candidates.h b/ui/ozone/platform/drm/common/drm_overlay_candidates.h
new file mode 100644
index 0000000..b0b49fb
--- /dev/null
+++ b/ui/ozone/platform/drm/common/drm_overlay_candidates.h
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_CANDIDATES_H_
+#define UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_CANDIDATES_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/public/overlay_candidates_ozone.h"
+
+namespace ui {
+class DrmOverlayManager;
+class OverlaySurfaceCandidate;
+
+// OverlayCandidatesOzone implementation that delegates decisions to
+// DrmOverlayManager.
+class DrmOverlayCandidates : public OverlayCandidatesOzone {
+ public:
+  DrmOverlayCandidates(DrmOverlayManager* manager,
+                       gfx::AcceleratedWidget widget);
+  ~DrmOverlayCandidates() override;
+
+  // OverlayCandidatesOzone:
+  void CheckOverlaySupport(
+      std::vector<OverlaySurfaceCandidate>* candidates) override;
+
+ private:
+  DrmOverlayManager* const overlay_manager_;  // Not owned.
+  const gfx::AcceleratedWidget widget_;
+
+  DISALLOW_COPY_AND_ASSIGN(DrmOverlayCandidates);
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_CANDIDATES_H_
diff --git a/ui/ozone/platform/drm/common/drm_overlay_manager.cc b/ui/ozone/platform/drm/common/drm_overlay_manager.cc
new file mode 100644
index 0000000..1749e047
--- /dev/null
+++ b/ui/ozone/platform/drm/common/drm_overlay_manager.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 "ui/ozone/platform/drm/common/drm_overlay_manager.h"
+
+#include "ui/ozone/platform/drm/common/drm_overlay_candidates.h"
+#include "ui/ozone/public/overlay_surface_candidate.h"
+
+namespace ui {
+
+DrmOverlayManager::DrmOverlayManager() = default;
+
+DrmOverlayManager::~DrmOverlayManager() = default;
+
+std::unique_ptr<OverlayCandidatesOzone>
+DrmOverlayManager::CreateOverlayCandidates(gfx::AcceleratedWidget widget) {
+  return std::make_unique<DrmOverlayCandidates>(this, widget);
+}
+
+bool DrmOverlayManager::SupportsOverlays() const {
+  return supports_overlays_;
+}
+
+}  // namespace ui
diff --git a/ui/ozone/platform/drm/common/drm_overlay_manager.h b/ui/ozone/platform/drm/common/drm_overlay_manager.h
new file mode 100644
index 0000000..e1e5fa1c
--- /dev/null
+++ b/ui/ozone/platform/drm/common/drm_overlay_manager.h
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_MANAGER_H_
+#define UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_MANAGER_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "ui/ozone/public/overlay_manager_ozone.h"
+
+namespace ui {
+class OverlayCandidatesOzone;
+class OverlaySurfaceCandidate;
+
+// Ozone DRM extension of the OverlayManagerOzone interface.
+class DrmOverlayManager : public OverlayManagerOzone {
+ public:
+  DrmOverlayManager();
+  ~DrmOverlayManager() override;
+
+  void set_supports_overlays(bool supports_overlays) {
+    supports_overlays_ = supports_overlays;
+  }
+
+  // OverlayManagerOzone:
+  std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates(
+      gfx::AcceleratedWidget w) override;
+  bool SupportsOverlays() const override;
+
+  // Resets the cache of OverlaySurfaceCandidates and if they can be displayed
+  // as an overlay. For use when display configuration changes.
+  virtual void ResetCache() = 0;
+
+  // Checks if overlay candidates can be displayed as overlays. Modifies
+  // |candidates| to indicate if they can.
+  virtual void CheckOverlaySupport(
+      std::vector<OverlaySurfaceCandidate>* candidates,
+      gfx::AcceleratedWidget widget) = 0;
+
+ private:
+  // Whether we have DRM atomic capabilities and can support HW overlays.
+  bool supports_overlays_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(DrmOverlayManager);
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_MANAGER_H_
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/ui/ozone/platform/drm/host/drm_display_host_manager.cc
index a47c5f9b..de123a26 100644
--- a/ui/ozone/platform/drm/host/drm_display_host_manager.cc
+++ b/ui/ozone/platform/drm/host/drm_display_host_manager.cc
@@ -24,7 +24,7 @@
 #include "ui/ozone/platform/drm/host/drm_device_handle.h"
 #include "ui/ozone/platform/drm/host/drm_display_host.h"
 #include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
 #include "ui/ozone/platform/drm/host/gpu_thread_adapter.h"
 
 namespace ui {
@@ -111,7 +111,7 @@
 DrmDisplayHostManager::DrmDisplayHostManager(
     GpuThreadAdapter* proxy,
     DeviceManager* device_manager,
-    DrmOverlayManager* overlay_manager,
+    DrmOverlayManagerHost* overlay_manager,
     InputControllerEvdev* input_controller)
     : proxy_(proxy),
       device_manager_(device_manager),
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.h b/ui/ozone/platform/drm/host/drm_display_host_manager.h
index 3b77e9b..3e745d7 100644
--- a/ui/ozone/platform/drm/host/drm_display_host_manager.h
+++ b/ui/ozone/platform/drm/host/drm_display_host_manager.h
@@ -28,7 +28,7 @@
 class DrmDisplayHost;
 class DrmDisplayHostManager;
 class DrmNativeDisplayDelegate;
-class DrmOverlayManager;
+class DrmOverlayManagerHost;
 class GpuThreadAdapter;
 
 struct DisplaySnapshot_Params;
@@ -40,7 +40,7 @@
  public:
   DrmDisplayHostManager(GpuThreadAdapter* proxy,
                         DeviceManager* device_manager,
-                        DrmOverlayManager* overlay_manager,
+                        DrmOverlayManagerHost* overlay_manager,
                         InputControllerEvdev* input_controller);
   ~DrmDisplayHostManager() override;
 
@@ -100,7 +100,7 @@
 
   GpuThreadAdapter* const proxy_;                 // Not owned.
   DeviceManager* const device_manager_;           // Not owned.
-  DrmOverlayManager* const overlay_manager_;      // Not owned.
+  DrmOverlayManagerHost* const overlay_manager_;  // Not owned.
   InputControllerEvdev* const input_controller_;  // Not owned.
 
   DrmNativeDisplayDelegate* delegate_ = nullptr;  // Not owned.
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
index 1a2fea673..e4677fb81 100644
--- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
+++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
@@ -14,11 +14,11 @@
 #include "ui/base/ui_base_switches.h"
 #include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
 #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
+#include "ui/ozone/platform/drm/common/drm_overlay_candidates.h"
 #include "ui/ozone/platform/drm/common/drm_util.h"
 #include "ui/ozone/platform/drm/host/drm_cursor.h"
 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
 #include "ui/ozone/platform/drm/host/gpu_thread_observer.h"
 
 namespace ui {
@@ -304,7 +304,7 @@
 
 // Overlays
 void DrmGpuPlatformSupportHost::RegisterHandlerForDrmOverlayManager(
-    DrmOverlayManager* handler) {
+    DrmOverlayManagerHost* handler) {
   overlay_manager_ = handler;
 }
 
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
index 45d45b8a..6d9746e 100644
--- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
+++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
@@ -24,7 +24,7 @@
 
 class DrmCursor;
 class DrmDisplayHostMananger;
-class DrmOverlayManager;
+class DrmOverlayManagerHost;
 class GpuThreadObserver;
 
 class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
@@ -70,12 +70,13 @@
                             base::ScopedFD fd) override;
   bool GpuRemoveGraphicsDevice(const base::FilePath& path) override;
 
-  // Methods needed for DrmOverlayManager.
-  // Methods for DrmOverlayManager.
-  void RegisterHandlerForDrmOverlayManager(DrmOverlayManager* handler) override;
+  // Methods needed for DrmOverlayManagerHost.
+  // Methods for DrmOverlayManagerHost.
+  void RegisterHandlerForDrmOverlayManager(
+      DrmOverlayManagerHost* handler) override;
   void UnRegisterHandlerForDrmOverlayManager() override;
 
-  // Services needed by DrmOverlayManager
+  // Services needed by DrmOverlayManagerHost
   bool GpuCheckOverlayCapabilities(
       gfx::AcceleratedWidget widget,
       const OverlaySurfaceCandidateList& new_params) override;
@@ -126,7 +127,7 @@
   base::Callback<void(IPC::Message*)> send_callback_;
 
   DrmDisplayHostManager* display_manager_;  // Not owned.
-  DrmOverlayManager* overlay_manager_;      // Not owned.
+  DrmOverlayManagerHost* overlay_manager_;  // Not owned.
 
   DrmCursor* const cursor_;  // Not owned.
   base::ObserverList<GpuThreadObserver>::Unchecked gpu_thread_observers_;
diff --git a/ui/ozone/platform/drm/host/drm_overlay_candidates_host.cc b/ui/ozone/platform/drm/host/drm_overlay_candidates_host.cc
deleted file mode 100644
index a04330d..0000000
--- a/ui/ozone/platform/drm/host/drm_overlay_candidates_host.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h"
-
-#include <stddef.h>
-
-#include <algorithm>
-
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/ozone/common/gpu/ozone_gpu_messages.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
-#include "ui/ozone/platform/drm/host/drm_window_host.h"
-#include "ui/ozone/public/overlay_manager_ozone.h"
-
-namespace ui {
-
-DrmOverlayCandidatesHost::DrmOverlayCandidatesHost(
-    DrmOverlayManager* manager,
-    gfx::AcceleratedWidget widget)
-    : overlay_manager_(manager), widget_(widget) {}
-
-DrmOverlayCandidatesHost::~DrmOverlayCandidatesHost() {}
-
-void DrmOverlayCandidatesHost::CheckOverlaySupport(
-    OverlaySurfaceCandidateList* candidates) {
-  overlay_manager_->CheckOverlaySupport(candidates, widget_);
-}
-
-
-}  // namespace ui
diff --git a/ui/ozone/platform/drm/host/drm_overlay_candidates_host.h b/ui/ozone/platform/drm/host/drm_overlay_candidates_host.h
deleted file mode 100644
index 6e591602..0000000
--- a/ui/ozone/platform/drm/host/drm_overlay_candidates_host.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_CANDIDATES_HOST_H_
-#define UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_CANDIDATES_HOST_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <vector>
-
-#include "base/containers/mru_cache.h"
-#include "base/macros.h"
-#include "ui/ozone/platform/drm/host/gpu_thread_adapter.h"
-#include "ui/ozone/platform/drm/host/gpu_thread_observer.h"
-#include "ui/ozone/public/overlay_candidates_ozone.h"
-
-namespace ui {
-
-class DrmOverlayManager;
-
-// This is an implementation of OverlayCandidatesOzone where the driver is asked
-// about overlay capabilities via IPC. We have no way of querying abstract
-// capabilities, only if a particular configuration is supported or not.
-// Each time we we are asked if a particular configuration is supported, if we
-// have not seen that configuration before, it is IPCed to the GPU via
-// OzoneGpuMsg_CheckOverlayCapabilities; a test commit is then performed and
-// the result is returned in OzoneHostMsg_OverlayCapabilitiesReceived. Testing
-// is asynchronous, until the reply arrives that configuration will be failed.
-//
-// All OverlayCandidatesOzone objects share a single cache of tested
-// configurations stored in the overlay manager.
-class DrmOverlayCandidatesHost : public OverlayCandidatesOzone {
- public:
-  DrmOverlayCandidatesHost(DrmOverlayManager* manager_core,
-                           gfx::AcceleratedWidget widget);
-  ~DrmOverlayCandidatesHost() override;
-
-  void CheckOverlaySupport(OverlaySurfaceCandidateList* candidates) override;
-
- private:
-  DrmOverlayManager* const overlay_manager_;  // Not owned.
-  const gfx::AcceleratedWidget widget_;
-
-  DISALLOW_COPY_AND_ASSIGN(DrmOverlayCandidatesHost);
-};
-
-}  // namespace ui
-
-#endif  // UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_CANDIDATES_HOST_H_
diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.cc b/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc
similarity index 79%
rename from ui/ozone/platform/drm/host/drm_overlay_manager.cc
rename to ui/ozone/platform/drm/host/drm_overlay_manager_host.cc
index 3ac13112..b8a6b3793 100644
--- a/ui/ozone/platform/drm/host/drm_overlay_manager.cc
+++ b/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
 
 #include <stddef.h>
 
@@ -12,7 +12,6 @@
 #include "base/trace_event/trace_event.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/ozone/platform/drm/common/drm_util.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h"
 #include "ui/ozone/platform/drm/host/drm_window_host.h"
 #include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
 #include "ui/ozone/public/overlay_surface_candidate.h"
@@ -30,29 +29,21 @@
 const int kThrottleRequestSize = 3;
 }  // namespace
 
-DrmOverlayManager::DrmOverlayManager(GpuThreadAdapter* proxy,
-                                     DrmWindowHostManager* window_manager)
+DrmOverlayManagerHost::DrmOverlayManagerHost(
+    GpuThreadAdapter* proxy,
+    DrmWindowHostManager* window_manager)
     : proxy_(proxy), window_manager_(window_manager), cache_(kMaxCacheSize) {
   proxy_->RegisterHandlerForDrmOverlayManager(this);
 }
 
-DrmOverlayManager::~DrmOverlayManager() {
+DrmOverlayManagerHost::~DrmOverlayManagerHost() {
   proxy_->UnRegisterHandlerForDrmOverlayManager();
 }
 
-std::unique_ptr<OverlayCandidatesOzone>
-DrmOverlayManager::CreateOverlayCandidates(gfx::AcceleratedWidget w) {
-  return std::make_unique<DrmOverlayCandidatesHost>(this, w);
-}
-
-bool DrmOverlayManager::SupportsOverlays() const {
-  return supports_overlays_;
-}
-
-void DrmOverlayManager::CheckOverlaySupport(
+void DrmOverlayManagerHost::CheckOverlaySupport(
     OverlayCandidatesOzone::OverlaySurfaceCandidateList* candidates,
     gfx::AcceleratedWidget widget) {
-  TRACE_EVENT0("hwoverlays", "DrmOverlayManager::CheckOverlaySupport");
+  TRACE_EVENT0("hwoverlays", "DrmOverlayManagerHost::CheckOverlaySupport");
 
   OverlaySurfaceCandidateList result_candidates;
   for (auto& candidate : *candidates) {
@@ -112,36 +103,29 @@
   }
 }
 
-void DrmOverlayManager::ResetCache() {
+void DrmOverlayManagerHost::ResetCache() {
   base::AutoLock lock(cache_lock_);
   cache_.Clear();
 }
 
-DrmOverlayManager::OverlayValidationCacheValue::OverlayValidationCacheValue() =
-    default;
-
-DrmOverlayManager::OverlayValidationCacheValue::OverlayValidationCacheValue(
-    const OverlayValidationCacheValue&) = default;
-DrmOverlayManager::OverlayValidationCacheValue::~OverlayValidationCacheValue() =
-    default;
-
-void DrmOverlayManager::SendOverlayValidationRequest(
+void DrmOverlayManagerHost::SendOverlayValidationRequest(
     const OverlaySurfaceCandidateList& candidates,
     gfx::AcceleratedWidget widget) const {
   if (!proxy_->IsConnected())
     return;
   TRACE_EVENT_ASYNC_BEGIN0(
-      "hwoverlays", "DrmOverlayManager::SendOverlayValidationRequest", this);
+      "hwoverlays", "DrmOverlayManagerHost::SendOverlayValidationRequest",
+      this);
   proxy_->GpuCheckOverlayCapabilities(widget, candidates);
 }
 
-void DrmOverlayManager::GpuSentOverlayResult(
+void DrmOverlayManagerHost::GpuSentOverlayResult(
     gfx::AcceleratedWidget widget,
     const OverlaySurfaceCandidateList& candidates,
     const OverlayStatusList& returns) {
-  TRACE_EVENT_ASYNC_END0(
-      "hwoverlays", "DrmOverlayManager::SendOverlayValidationRequest response",
-      this);
+  TRACE_EVENT_ASYNC_END0("hwoverlays",
+                         "DrmOverlayManagerHost::SendOverlayValidationRequest",
+                         this);
   base::AutoLock lock(cache_lock_);
   auto iter = cache_.Peek(candidates);
   if (iter != cache_.end()) {
@@ -149,7 +133,7 @@
   }
 }
 
-bool DrmOverlayManager::CanHandleCandidate(
+bool DrmOverlayManagerHost::CanHandleCandidate(
     const OverlaySurfaceCandidate& candidate,
     gfx::AcceleratedWidget widget) const {
   if (candidate.buffer_size.IsEmpty())
@@ -179,4 +163,11 @@
   return true;
 }
 
+DrmOverlayManagerHost::OverlayValidationCacheValue::
+    OverlayValidationCacheValue() = default;
+DrmOverlayManagerHost::OverlayValidationCacheValue::OverlayValidationCacheValue(
+    const OverlayValidationCacheValue&) = default;
+DrmOverlayManagerHost::OverlayValidationCacheValue::
+    ~OverlayValidationCacheValue() = default;
+
 }  // namespace ui
diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.h b/ui/ozone/platform/drm/host/drm_overlay_manager_host.h
similarity index 63%
rename from ui/ozone/platform/drm/host/drm_overlay_manager.h
rename to ui/ozone/platform/drm/host/drm_overlay_manager_host.h
index ea39854..84b82c6 100644
--- a/ui/ozone/platform/drm/host/drm_overlay_manager.h
+++ b/ui/ozone/platform/drm/host/drm_overlay_manager_host.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 UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_H_
-#define UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_H_
+#ifndef UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
+#define UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
 
 #include <stdint.h>
 
@@ -12,29 +12,36 @@
 #include "base/containers/mru_cache.h"
 #include "base/macros.h"
 #include "base/synchronization/lock.h"
+#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
 #include "ui/ozone/platform/drm/host/gpu_thread_adapter.h"
 #include "ui/ozone/public/overlay_candidates_ozone.h"
-#include "ui/ozone/public/overlay_manager_ozone.h"
 
 namespace ui {
 class DrmWindowHostManager;
 class OverlaySurfaceCandidate;
 
-class DrmOverlayManager : public OverlayManagerOzone {
+// This is an implementation of DrmOverlayManager where the driver is asked
+// about overlay capabilities via IPC. We have no way of querying abstract
+// capabilities, only if a particular configuration is supported or not.
+// Each time we we are asked if a particular configuration is supported, if we
+// have not seen that configuration before, it is IPCed to the GPU via
+// OzoneGpuMsg_CheckOverlayCapabilities, a test commit is then performed and
+// the result is returned in OzoneHostMsg_OverlayCapabilitiesReceived. Testing
+// is asynchronous, until the reply arrives that configuration will be failed.
+//
+// All widgets share a single cache of tested configurations stored in the
+// overlay manager.
+class DrmOverlayManagerHost : public DrmOverlayManager {
  public:
-  DrmOverlayManager(GpuThreadAdapter* proxy,
-                    DrmWindowHostManager* window_manager);
-  ~DrmOverlayManager() override;
+  DrmOverlayManagerHost(GpuThreadAdapter* proxy,
+                        DrmWindowHostManager* window_manager);
+  ~DrmOverlayManagerHost() override;
 
-  // OverlayManagerOzone:
-  std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates(
-      gfx::AcceleratedWidget w) override;
-
-  bool SupportsOverlays() const override;
-
-  // Invoked on changes to the window (aka display) that require re-populating
-  // the cache from the DRM thread.
-  void ResetCache();
+  // DrmOverlayManager:
+  void ResetCache() override;
+  void CheckOverlaySupport(
+      OverlayCandidatesOzone::OverlaySurfaceCandidateList* candidates,
+      gfx::AcceleratedWidget widget) override;
 
   // Communication-free implementations of actions performed in response to
   // messages from the GPU thread.
@@ -42,13 +49,6 @@
                             const OverlaySurfaceCandidateList& params,
                             const OverlayStatusList& returns);
 
-  // Service method for DrmOverlayCandidatesHost
-  void CheckOverlaySupport(
-      OverlayCandidatesOzone::OverlaySurfaceCandidateList* candidates,
-      gfx::AcceleratedWidget widget);
-
-  void set_supports_overlays(bool yes) { supports_overlays_ = yes; }
-
  private:
   // Value for the request cache, that keeps track of how many times a
   // specific validation has been requested, if there is a GPU validation
@@ -67,9 +67,6 @@
   bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
                           gfx::AcceleratedWidget widget) const;
 
-  // Whether we have DRM atomic capabilities and we can support HW overlays.
-  bool supports_overlays_ = false;
-
   GpuThreadAdapter* const proxy_;               // Not owned.
   DrmWindowHostManager* const window_manager_;  // Not owned.
 
@@ -84,9 +81,9 @@
   // the lock, but will require farther refactoring.
   base::Lock cache_lock_;
 
-  DISALLOW_COPY_AND_ASSIGN(DrmOverlayManager);
+  DISALLOW_COPY_AND_ASSIGN(DrmOverlayManagerHost);
 };
 
 }  // namespace ui
 
-#endif  // UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_H_
+#endif  // UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
diff --git a/ui/ozone/platform/drm/host/drm_window_host.cc b/ui/ozone/platform/drm/host/drm_window_host.cc
index 66e8b55..0985ef4 100644
--- a/ui/ozone/platform/drm/host/drm_window_host.cc
+++ b/ui/ozone/platform/drm/host/drm_window_host.cc
@@ -11,11 +11,12 @@
 #include "ui/events/ozone/evdev/event_factory_evdev.h"
 #include "ui/events/ozone/events_ozone.h"
 #include "ui/events/platform/platform_event_source.h"
+#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
 #include "ui/ozone/platform/drm/host/drm_cursor.h"
 #include "ui/ozone/platform/drm/host/drm_display_host.h"
 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
 #include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
+#include "ui/ozone/platform/drm/host/gpu_thread_adapter.h"
 #include "ui/platform_window/platform_window_delegate.h"
 
 namespace ui {
diff --git a/ui/ozone/platform/drm/host/gpu_thread_adapter.h b/ui/ozone/platform/drm/host/gpu_thread_adapter.h
index 7668d18..9b5db62c 100644
--- a/ui/ozone/platform/drm/host/gpu_thread_adapter.h
+++ b/ui/ozone/platform/drm/host/gpu_thread_adapter.h
@@ -15,7 +15,7 @@
 namespace ui {
 
 class DrmDisplayHostManager;
-class DrmOverlayManager;
+class DrmOverlayManagerHost;
 class GpuThreadObserver;
 
 // Provides the services that the various host components need
@@ -41,12 +41,12 @@
                                     base::ScopedFD fd) = 0;
   virtual bool GpuRemoveGraphicsDevice(const base::FilePath& path) = 0;
 
-  // Methods for DrmOverlayManager.
+  // Methods for DrmOverlayManagerHost.
   virtual void RegisterHandlerForDrmOverlayManager(
-      DrmOverlayManager* handler) = 0;
+      DrmOverlayManagerHost* handler) = 0;
   virtual void UnRegisterHandlerForDrmOverlayManager() = 0;
 
-  // Services needed by DrmOverlayManager
+  // Services needed by DrmOverlayManagerHost
   virtual bool GpuCheckOverlayCapabilities(
       gfx::AcceleratedWidget widget,
       const OverlaySurfaceCandidateList& overlays) = 0;
diff --git a/ui/ozone/platform/drm/host/host_drm_device.cc b/ui/ozone/platform/drm/host/host_drm_device.cc
index 35446c8e..a82b7e9c 100644
--- a/ui/ozone/platform/drm/host/host_drm_device.cc
+++ b/ui/ozone/platform/drm/host/host_drm_device.cc
@@ -15,7 +15,7 @@
 #include "ui/ozone/platform/drm/common/drm_util.h"
 #include "ui/ozone/platform/drm/host/drm_device_connector.h"
 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
 #include "ui/ozone/platform/drm/host/host_cursor_proxy.h"
 
 namespace ui {
@@ -91,7 +91,7 @@
 }
 
 void HostDrmDevice::ProvideManagers(DrmDisplayHostManager* display_manager,
-                                    DrmOverlayManager* overlay_manager) {
+                                    DrmOverlayManagerHost* overlay_manager) {
   display_manager_ = display_manager;
   overlay_manager_ = overlay_manager;
 }
@@ -174,9 +174,9 @@
   return true;
 }
 
-// Services needed for DrmOverlayManager.
+// Services needed for DrmOverlayManagerHost.
 void HostDrmDevice::RegisterHandlerForDrmOverlayManager(
-    DrmOverlayManager* handler) {
+    DrmOverlayManagerHost* handler) {
   // TODO(rjkroege): Permit overlay manager to run in Viz when the display
   // compositor runs in Viz.
   DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
diff --git a/ui/ozone/platform/drm/host/host_drm_device.h b/ui/ozone/platform/drm/host/host_drm_device.h
index 3372987d..30f61c1 100644
--- a/ui/ozone/platform/drm/host/host_drm_device.h
+++ b/ui/ozone/platform/drm/host/host_drm_device.h
@@ -24,7 +24,7 @@
 
 namespace ui {
 class DrmDisplayHostManager;
-class DrmOverlayManager;
+class DrmOverlayManagerHost;
 class GpuThreadObserver;
 class DrmDeviceConnector;
 class HostCursorProxy;
@@ -46,7 +46,7 @@
   void BlockingStartDrmDevice();
 
   void ProvideManagers(DrmDisplayHostManager* display_manager,
-                       DrmOverlayManager* overlay_manager);
+                       DrmOverlayManagerHost* overlay_manager);
 
   void OnGpuServiceLaunched(ui::ozone::mojom::DrmDevicePtr drm_device_ptr,
                             ui::ozone::mojom::DeviceCursorPtr cursor_ptr_ui,
@@ -75,8 +75,9 @@
                             base::ScopedFD fd) override;
   bool GpuRemoveGraphicsDevice(const base::FilePath& path) override;
 
-  // Services needed for DrmOverlayManager.
-  void RegisterHandlerForDrmOverlayManager(DrmOverlayManager* handler) override;
+  // Services needed for DrmOverlayManagerHost.
+  void RegisterHandlerForDrmOverlayManager(
+      DrmOverlayManagerHost* handler) override;
   void UnRegisterHandlerForDrmOverlayManager() override;
   bool GpuCheckOverlayCapabilities(
       gfx::AcceleratedWidget widget,
@@ -150,7 +151,7 @@
   ui::ozone::mojom::DrmDevicePtr drm_device_ptr_compositor_;
 
   DrmDisplayHostManager* display_manager_;  // Not owned.
-  DrmOverlayManager* overlay_manager_;      // Not owned.
+  DrmOverlayManagerHost* overlay_manager_;  // Not owned.
   DrmCursor* const cursor_;                 // Not owned.
 
   std::unique_ptr<HostCursorProxy> cursor_proxy_;
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc
index 339aef4..096aa02 100644
--- a/ui/ozone/platform/drm/ozone_platform_gbm.cc
+++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -41,7 +41,7 @@
 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
 #include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
 #include "ui/ozone/platform/drm/host/drm_window_host.h"
 #include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
 #include "ui/ozone/platform/drm/host/host_drm_device.h"
@@ -237,18 +237,20 @@
       adapter = gpu_platform_support_host_.get();
     }
 
-    overlay_manager_.reset(
-        new DrmOverlayManager(adapter, window_manager_.get()));
+    auto overlay_manager_host =
+        std::make_unique<DrmOverlayManagerHost>(adapter, window_manager_.get());
     display_manager_.reset(new DrmDisplayHostManager(
-        adapter, device_manager_.get(), overlay_manager_.get(),
+        adapter, device_manager_.get(), overlay_manager_host.get(),
         event_factory_ozone_->input_controller()));
     cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone);
 
     if (using_mojo_) {
       host_drm_device_->ProvideManagers(display_manager_.get(),
-                                        overlay_manager_.get());
+                                        overlay_manager_host.get());
       host_drm_device_->AsyncStartDrmDevice(*drm_device_connector_);
     }
+
+    overlay_manager_ = std::move(overlay_manager_host);
   }
 
   void InitializeGPU(const InitParams& args) override {
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js
index aeaa6c0..9578da2 100644
--- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js
+++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js
@@ -161,6 +161,7 @@
       'onTicksChanged_(ticks.*)',
       'updateLabelAndAria_(value, min, max)',
       'updateKnobAndBar_(value, min, max)',
+      'updateValue_(value, min, max)',
     ],
 
     listeners: {
diff --git a/ui/webui/resources/polymer_resources.grdp b/ui/webui/resources/polymer_resources.grdp
index a0c34db..1a64378 100644
--- a/ui/webui/resources/polymer_resources.grdp
+++ b/ui/webui/resources/polymer_resources.grdp
@@ -24,6 +24,10 @@
              file="../../../third_party/polymer/v1_0/components-chromium/font-roboto/roboto.html"
              type="chrome_html"
              compress="gzip" />
+  <structure name="IDR_POLYMER_1_0_HTML_IMPORTS_HTML_IMPORTS_MIN_JS"
+             file="../../../third_party/polymer/v1_0/components-chromium/html-imports/html-imports.min.js"
+             type="chrome_html"
+             compress="gzip" />
   <structure name="IDR_POLYMER_1_0_IRON_A11Y_ANNOUNCER_IRON_A11Y_ANNOUNCER_EXTRACTED_JS"
              file="../../../third_party/polymer/v1_0/components-chromium/iron-a11y-announcer/iron-a11y-announcer-extracted.js"
              type="chrome_html"