diff --git a/DEPS b/DEPS
index 10864f6..a338b199 100644
--- a/DEPS
+++ b/DEPS
@@ -162,7 +162,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'c091a1b5c085ad3fccc1507caaf2be7ff124d62a',
+  'skia_revision': 'c13cb6e62441c499c2dca6b899c67f2c3e9208fe',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -174,7 +174,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '0b8eca7953499f9eb6459761aff1114f03bfa0e4',
+  'angle_revision': '9dbfeac8b553427eabe2c4b5bce322efecc0b440',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -182,7 +182,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '881c56bc068704d45398bd7dedd7dcab6461e999',
+  'pdfium_revision': '9fafe62237ad4cf5c502f9f81a5ce302fc69db3c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -225,7 +225,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': '050abd8dd5c49167d4d33864f3c078d270d271af',
+  'catapult_revision': 'c5f9c068212598f72a2f07356be1d7452ce9861b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -281,7 +281,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': '7f7236f1eba0afae2669ea777896f0435be4c96d',
+  'spv_tools_revision': 'c0e9807094ef6e345ef0a4d5f17af81af063cd27',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -1414,7 +1414,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'abaae129d9a0c6e1e092067e0b105475df43352e',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '55f663f5ddff7be2943a528fc6896c220de45599',
+    Var('webrtc_git') + '/src.git' + '@' + '9a91161b9f65df0cbe64009827ca6b8d1c172675',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1455,7 +1455,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ea8664557d2e1199be7251933953f46f5a8cd39d',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@61336619eaf0d77cea9906b16f26377eb6441c4f',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 917e366..8c17807 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -220,7 +220,7 @@
 
 void PassMojoCookieManagerToAwCookieManager(
     CookieManager* cookie_manager,
-    const network::mojom::NetworkContextPtr& network_context) {
+    const mojo::Remote<network::mojom::NetworkContext>& network_context) {
   // Get the CookieManager from the NetworkContext.
   mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote;
   network_context->GetCookieManager(
@@ -342,7 +342,8 @@
   content::GetNetworkService()->SetUpHttpAuth(std::move(auth_static_params));
 }
 
-network::mojom::NetworkContextPtr AwContentBrowserClient::CreateNetworkContext(
+mojo::Remote<network::mojom::NetworkContext>
+AwContentBrowserClient::CreateNetworkContext(
     content::BrowserContext* context,
     bool in_memory,
     const base::FilePath& relative_partition_path) {
@@ -352,14 +353,14 @@
       AwBrowserProcess::GetInstance()->CreateHttpAuthDynamicParams());
 
   auto* aw_context = static_cast<AwBrowserContext*>(context);
-  network::mojom::NetworkContextPtr network_context;
+  mojo::Remote<network::mojom::NetworkContext> network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       aw_context->GetNetworkContextParams(in_memory, relative_partition_path);
 #if DCHECK_IS_ON()
   g_created_network_context_params = true;
 #endif
   content::GetNetworkService()->CreateNetworkContext(
-      MakeRequest(&network_context), std::move(context_params));
+      network_context.BindNewPipeAndPassReceiver(), std::move(context_params));
 
   // Pass a CookieManager to the code supporting AwCookieManager.java (i.e., the
   // Cookies APIs).
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index f67f2d1e..32acca9 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -14,6 +14,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "content/public/browser/content_browser_client.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 
 namespace content {
@@ -54,7 +55,7 @@
 
   void OnNetworkServiceCreated(
       network::mojom::NetworkService* network_service) override;
-  network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       content::BrowserContext* context,
       bool in_memory,
       const base::FilePath& relative_partition_path) override;
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc
index 4e4981a..3572029 100644
--- a/ash/login/login_screen_controller.cc
+++ b/ash/login/login_screen_controller.cc
@@ -25,7 +25,7 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/debug/alias.h"
-#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/session_manager/session_manager_types.h"
@@ -124,9 +124,10 @@
 
   authentication_stage_ = AuthenticationStage::kDoAuthenticate;
 
-  int dummy_value;
-  bool is_pin =
-      authenticated_by_pin && base::StringToInt(password, &dummy_value);
+  // Checking if the password is only formed of numbers with base::StringToInt
+  // will easily fail due to numeric limits. ContainsOnlyChars is used instead.
+  const bool is_pin =
+      authenticated_by_pin && base::ContainsOnlyChars(password, "0123456789");
   client_->AuthenticateUserWithPasswordOrPin(
       account_id, password, is_pin,
       base::BindOnce(&LoginScreenController::OnAuthenticateComplete,
diff --git a/ash/login/login_screen_controller_unittest.cc b/ash/login/login_screen_controller_unittest.cc
index 3d1f2e5..e60beff 100644
--- a/ash/login/login_screen_controller_unittest.cc
+++ b/ash/login/login_screen_controller_unittest.cc
@@ -70,7 +70,8 @@
       Shell::Get()->session_controller()->GetLastActiveUserPrefService();
   EXPECT_TRUE(prefs->FindPreference(prefs::kQuickUnlockPinSalt));
 
-  std::string pin = "123456";
+  // Use a long PIN (N > 2^64) for the test to ensure that there is no overflow.
+  std::string pin = "12345678901234567890";
   EXPECT_CALL(*client, AuthenticateUserWithPasswordOrPin_(id, pin, true, _));
   base::RunLoop run_loop2;
   controller->AuthenticateUserWithPasswordOrPin(
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 24f77bf..bddb038 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -269,6 +269,24 @@
 inline const char16* as_u16cstr(WStringPiece str) {
   return reinterpret_cast<const char16*>(str.data());
 }
+
+// Utility functions to convert between base::WStringPiece and
+// base::StringPiece16.
+inline WStringPiece AsWStringPiece(StringPiece16 str) {
+  return WStringPiece(as_wcstr(str.data()), str.size());
+}
+
+inline StringPiece16 AsStringPiece16(WStringPiece str) {
+  return StringPiece16(as_u16cstr(str.data()), str.size());
+}
+
+inline std::wstring AsWString(StringPiece16 str) {
+  return std::wstring(as_wcstr(str.data()), str.size());
+}
+
+inline string16 AsString16(WStringPiece str) {
+  return string16(as_u16cstr(str.data()), str.size());
+}
 #endif  // defined(WCHAR_T_IS_UTF16)
 
 // Trims any whitespace from either end of the input string.
diff --git a/base/strings/string_util_win.h b/base/strings/string_util_win.h
index 7f260bf..791f60e 100644
--- a/base/strings/string_util_win.h
+++ b/base/strings/string_util_win.h
@@ -39,6 +39,19 @@
   return length;
 }
 
+// Windows only overload of base::WriteInto for std::wstring. See the comment
+// above the cross-platform version in //base/strings/string_util.h for details.
+// TODO(crbug.com/911896): Rename this to WriteInto once base::string16 is
+// std::u16string on all platforms and using the name WriteInto here no longer
+// causes redefinition errors.
+inline wchar_t* WriteIntoW(std::wstring* str, size_t length_with_null) {
+  // Note: As of C++11 std::strings are guaranteed to be 0-terminated. Thus it
+  // is enough to reserve space for one char less.
+  DCHECK_GE(length_with_null, 1u);
+  str->resize(length_with_null - 1);
+  return &((*str)[0]);
+}
+
 }  // namespace base
 
 #endif  // BASE_STRINGS_STRING_UTIL_WIN_H_
diff --git a/base/syslog_logging.cc b/base/syslog_logging.cc
index 68483efc..6b7280d 100644
--- a/base/syslog_logging.cc
+++ b/base/syslog_logging.cc
@@ -34,7 +34,7 @@
 std::string* g_event_source_name = nullptr;
 uint16_t g_category = 0;
 uint32_t g_event_id = 0;
-base::string16* g_user_sid = nullptr;
+std::wstring* g_user_sid = nullptr;
 
 }  // namespace
 
@@ -46,7 +46,7 @@
   g_category = category;
   g_event_id = event_id;
   DCHECK_EQ(nullptr, g_user_sid);
-  g_user_sid = new base::string16();
+  g_user_sid = new std::wstring();
   base::win::GetUserSidString(g_user_sid);
 }
 
@@ -102,7 +102,7 @@
   }
   LPCSTR strings[1] = {message.data()};
   PSID user_sid = nullptr;
-  if (!::ConvertStringSidToSid(base::as_wcstr(*g_user_sid), &user_sid)) {
+  if (!::ConvertStringSidToSid(g_user_sid->c_str(), &user_sid)) {
     stream() << " !!ERROR GETTING USER SID!!";
   }
 
diff --git a/base/system/sys_info_win.cc b/base/system/sys_info_win.cc
index 87650d8..a600296 100644
--- a/base/system/sys_info_win.cc
+++ b/base/system/sys_info_win.cc
@@ -171,9 +171,9 @@
   win::WmiComputerSystemInfo wmi_info = win::WmiComputerSystemInfo::Get();
 
   HardwareInfo info;
-  info.manufacturer = UTF16ToUTF8(wmi_info.manufacturer());
-  info.model = UTF16ToUTF8(wmi_info.model());
-  info.serial_number = UTF16ToUTF8(wmi_info.serial_number());
+  info.manufacturer = WideToUTF8(wmi_info.manufacturer());
+  info.model = WideToUTF8(wmi_info.model());
+  info.serial_number = WideToUTF8(wmi_info.serial_number());
   DCHECK(IsStringUTF8(info.manufacturer));
   DCHECK(IsStringUTF8(info.model));
   DCHECK(IsStringUTF8(info.serial_number));
diff --git a/base/test/test_reg_util_win.cc b/base/test/test_reg_util_win.cc
index ad368ca..3635bc9 100644
--- a/base/test/test_reg_util_win.cc
+++ b/base/test/test_reg_util_win.cc
@@ -9,6 +9,7 @@
 #include "base/guid.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -21,12 +22,11 @@
 
 namespace {
 
-const base::char16 kTimestampDelimiter[] = STRING16_LITERAL("$");
-const base::char16 kTempTestKeyPath[] =
-    STRING16_LITERAL("Software\\Chromium\\TempTestKeys");
+constexpr base::char16 kTimestampDelimiter[] = STRING16_LITERAL("$");
+constexpr wchar_t kTempTestKeyPath[] = L"Software\\Chromium\\TempTestKeys";
 
 void DeleteStaleTestKeys(const base::Time& now,
-                         const base::string16& test_key_root) {
+                         const std::wstring& test_key_root) {
   base::win::RegKey test_root_key;
   if (test_root_key.Open(HKEY_CURRENT_USER,
                          test_key_root.c_str(),
@@ -38,10 +38,10 @@
   base::win::RegistryKeyIterator iterator_test_root_key(HKEY_CURRENT_USER,
                                                         test_key_root.c_str());
   for (; iterator_test_root_key.Valid(); ++iterator_test_root_key) {
-    base::string16 key_name = iterator_test_root_key.Name();
-    std::vector<base::string16> tokens = base::SplitString(
-        key_name, kTimestampDelimiter, base::KEEP_WHITESPACE,
-        base::SPLIT_WANT_NONEMPTY);
+    std::wstring key_name = iterator_test_root_key.Name();
+    std::vector<base::StringPiece16> tokens = base::SplitStringPiece(
+        base::AsStringPiece16(key_name), kTimestampDelimiter,
+        base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
     if (tokens.empty())
       continue;
     int64_t key_name_as_number = 0;
@@ -59,27 +59,25 @@
   }
 }
 
-base::string16 GenerateTempKeyPath(const base::string16& test_key_root,
-                                   const base::Time& timestamp) {
-  base::string16 key_path = test_key_root;
-  key_path += STRING16_LITERAL("\\") +
-              base::NumberToString16(timestamp.ToInternalValue());
-  key_path += kTimestampDelimiter + base::ASCIIToUTF16(base::GenerateGUID());
-
-  return key_path;
+std::wstring GenerateTempKeyPath(const std::wstring& test_key_root,
+                                 const base::Time& timestamp) {
+  return base::AsWString(base::StrCat(
+      {base::AsStringPiece16(test_key_root), STRING16_LITERAL("\\"),
+       base::NumberToString16(timestamp.ToInternalValue()), kTimestampDelimiter,
+       base::ASCIIToUTF16(base::GenerateGUID())}));
 }
 
 }  // namespace
 
 RegistryOverrideManager::ScopedRegistryKeyOverride::ScopedRegistryKeyOverride(
     HKEY override,
-    const base::string16& key_path)
+    const std::wstring& key_path)
     : override_(override), key_path_(key_path) {}
 
 RegistryOverrideManager::
     ScopedRegistryKeyOverride::~ScopedRegistryKeyOverride() {
   ::RegOverridePredefKey(override_, NULL);
-  base::win::RegKey(HKEY_CURRENT_USER, STRING16_LITERAL(""), KEY_QUERY_VALUE)
+  base::win::RegKey(HKEY_CURRENT_USER, L"", KEY_QUERY_VALUE)
       .DeleteKey(key_path_.c_str());
 }
 
@@ -90,7 +88,7 @@
 
 RegistryOverrideManager::RegistryOverrideManager(
     const base::Time& timestamp,
-    const base::string16& test_key_root)
+    const std::wstring& test_key_root)
     : timestamp_(timestamp), test_key_root_(test_key_root) {
   DeleteStaleTestKeys(timestamp_, test_key_root_);
 }
@@ -102,8 +100,8 @@
 }
 
 void RegistryOverrideManager::OverrideRegistry(HKEY override,
-                                               base::string16* override_path) {
-  base::string16 key_path = GenerateTempKeyPath(test_key_root_, timestamp_);
+                                               std::wstring* override_path) {
+  std::wstring key_path = GenerateTempKeyPath(test_key_root_, timestamp_);
 
   base::win::RegKey temp_key;
   ASSERT_EQ(ERROR_SUCCESS, temp_key.Create(HKEY_CURRENT_USER, key_path.c_str(),
@@ -116,9 +114,8 @@
     override_path->assign(key_path);
 }
 
-base::string16 GenerateTempKeyPath() {
-  return GenerateTempKeyPath(base::string16(kTempTestKeyPath),
-                             base::Time::Now());
+std::wstring GenerateTempKeyPath() {
+  return GenerateTempKeyPath(kTempTestKeyPath, base::Time::Now());
 }
 
 }  // namespace registry_util
diff --git a/base/test/test_reg_util_win.h b/base/test/test_reg_util_win.h
index d74028a..0592ff7 100644
--- a/base/test/test_reg_util_win.h
+++ b/base/test/test_reg_util_win.h
@@ -7,10 +7,10 @@
 
 // Registry utility functions used only by tests.
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "base/macros.h"
-#include "base/strings/string16.h"
 #include "base/time/time.h"
 #include "base/win/registry.h"
 
@@ -42,7 +42,7 @@
   // Calls to these functions must be wrapped in ASSERT_NO_FATAL_FAILURE to
   // ensure that tests do not proceeed in case of failure to override.
   void OverrideRegistry(HKEY override);
-  void OverrideRegistry(HKEY override, base::string16* override_path);
+  void OverrideRegistry(HKEY override, std::wstring* override_path);
 
  private:
   friend class RegistryOverrideManagerTest;
@@ -50,24 +50,24 @@
   // Keeps track of one override.
   class ScopedRegistryKeyOverride {
    public:
-    ScopedRegistryKeyOverride(HKEY override, const base::string16& key_path);
+    ScopedRegistryKeyOverride(HKEY override, const std::wstring& key_path);
     ~ScopedRegistryKeyOverride();
 
    private:
     HKEY override_;
-    base::string16 key_path_;
+    std::wstring key_path_;
 
     DISALLOW_COPY_AND_ASSIGN(ScopedRegistryKeyOverride);
   };
 
   // Used for testing only.
   RegistryOverrideManager(const base::Time& timestamp,
-                          const base::string16& test_key_root);
+                          const std::wstring& test_key_root);
 
   base::Time timestamp_;
-  base::string16 guid_;
+  std::wstring guid_;
 
-  base::string16 test_key_root_;
+  std::wstring test_key_root_;
   std::vector<std::unique_ptr<ScopedRegistryKeyOverride>> overrides_;
 
   DISALLOW_COPY_AND_ASSIGN(RegistryOverrideManager);
@@ -75,7 +75,7 @@
 
 // Generates a temporary key path that will be eventually deleted
 // automatically if the process crashes.
-base::string16 GenerateTempKeyPath();
+std::wstring GenerateTempKeyPath();
 
 }  // namespace registry_util
 
diff --git a/base/test/test_reg_util_win_unittest.cc b/base/test/test_reg_util_win_unittest.cc
index b1a7e17f..12c1d6b 100644
--- a/base/test/test_reg_util_win_unittest.cc
+++ b/base/test/test_reg_util_win_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -15,9 +16,8 @@
 namespace registry_util {
 
 namespace {
-const base::char16 kTestKeyPath[] =
-    STRING16_LITERAL("Software\\Chromium\\Foo\\Baz\\TestKey");
-const base::char16 kTestValueName[] = STRING16_LITERAL("TestValue");
+const wchar_t kTestKeyPath[] = L"Software\\Chromium\\Foo\\Baz\\TestKey";
+const wchar_t kTestValueName[] = L"TestValue";
 }  // namespace
 
 class RegistryOverrideManagerTest : public testing::Test {
@@ -40,29 +40,29 @@
     key.DeleteKey(fake_test_key_root_.c_str());
   }
 
-  void AssertKeyExists(const base::string16& key_path) {
+  void AssertKeyExists(const std::wstring& key_path) {
     base::win::RegKey key;
     ASSERT_EQ(ERROR_SUCCESS,
               key.Open(HKEY_CURRENT_USER, key_path.c_str(), KEY_READ))
         << key_path << " does not exist.";
   }
 
-  void AssertKeyAbsent(const base::string16& key_path) {
+  void AssertKeyAbsent(const std::wstring& key_path) {
     base::win::RegKey key;
     ASSERT_NE(ERROR_SUCCESS,
               key.Open(HKEY_CURRENT_USER, key_path.c_str(), KEY_READ))
         << key_path << " exists but it should not.";
   }
 
-  void CreateKey(const base::string16& key_path) {
+  void CreateKey(const std::wstring& key_path) {
     base::win::RegKey key;
     ASSERT_EQ(ERROR_SUCCESS,
               key.Create(HKEY_CURRENT_USER, key_path.c_str(), KEY_ALL_ACCESS));
   }
 
-  base::string16 FakeOverrideManagerPath(const base::Time& time) {
-    return fake_test_key_root_ + STRING16_LITERAL("\\") +
-           base::NumberToString16(time.ToInternalValue());
+  std::wstring FakeOverrideManagerPath(const base::Time& time) {
+    return fake_test_key_root_ + L"\\" +
+           base::AsWString(base::NumberToString16(time.ToInternalValue()));
   }
 
   void CreateManager(const base::Time& timestamp) {
@@ -70,7 +70,7 @@
     manager_->OverrideRegistry(HKEY_CURRENT_USER);
   }
 
-  base::string16 fake_test_key_root_;
+  std::wstring fake_test_key_root_;
   std::unique_ptr<RegistryOverrideManager> manager_;
 };
 
@@ -105,15 +105,14 @@
   base::Time kTestTime;
   EXPECT_TRUE(base::Time::FromUTCExploded(kTestTimeExploded, &kTestTime));
 
-  base::string16 path_garbage =
-      fake_test_key_root_ + STRING16_LITERAL("\\Blah");
-  base::string16 path_very_stale =
+  std::wstring path_garbage = fake_test_key_root_ + L"\\Blah";
+  std::wstring path_very_stale =
       FakeOverrideManagerPath(kTestTime - base::TimeDelta::FromDays(100));
-  base::string16 path_stale =
+  std::wstring path_stale =
       FakeOverrideManagerPath(kTestTime - base::TimeDelta::FromDays(5));
-  base::string16 path_current =
+  std::wstring path_current =
       FakeOverrideManagerPath(kTestTime - base::TimeDelta::FromMinutes(1));
-  base::string16 path_future =
+  std::wstring path_future =
       FakeOverrideManagerPath(kTestTime + base::TimeDelta::FromMinutes(1));
 
   ASSERT_NO_FATAL_FAILURE(CreateKey(path_garbage));
diff --git a/base/test/test_shortcut_win.cc b/base/test/test_shortcut_win.cc
index 71766d5b7..9b5cb18a 100644
--- a/base/test/test_shortcut_win.cc
+++ b/base/test/test_shortcut_win.cc
@@ -22,8 +22,8 @@
 
 void ValidatePathsAreEqual(const FilePath& expected_path,
                            const FilePath& actual_path) {
-  char16 long_expected_path_chars[MAX_PATH] = {0};
-  char16 long_actual_path_chars[MAX_PATH] = {0};
+  wchar_t long_expected_path_chars[MAX_PATH] = {0};
+  wchar_t long_actual_path_chars[MAX_PATH] = {0};
 
   // If |expected_path| is empty confirm immediately that |actual_path| is also
   // empty.
@@ -34,16 +34,14 @@
 
   // Proceed with LongPathName matching which will also confirm the paths exist.
   EXPECT_NE(0U, ::GetLongPathName(as_wcstr(expected_path.value()),
-                                  as_writable_wcstr(long_expected_path_chars),
-                                  MAX_PATH))
+                                  long_expected_path_chars, MAX_PATH))
       << "Failed to get LongPathName of " << expected_path.value();
   EXPECT_NE(0U, ::GetLongPathName(as_wcstr(actual_path.value()),
-                                  as_writable_wcstr(long_actual_path_chars),
-                                  MAX_PATH))
+                                  long_actual_path_chars, MAX_PATH))
       << "Failed to get LongPathName of " << actual_path.value();
 
-  FilePath long_expected_path(long_expected_path_chars);
-  FilePath long_actual_path(long_actual_path_chars);
+  FilePath long_expected_path(AsStringPiece16(long_expected_path_chars));
+  FilePath long_actual_path(AsStringPiece16(long_actual_path_chars));
   EXPECT_FALSE(long_expected_path.empty());
   EXPECT_FALSE(long_actual_path.empty());
 
@@ -55,11 +53,11 @@
   Microsoft::WRL::ComPtr<IShellLink> i_shell_link;
   Microsoft::WRL::ComPtr<IPersistFile> i_persist_file;
 
-  char16 read_target[MAX_PATH] = {0};
-  char16 read_working_dir[MAX_PATH] = {0};
-  char16 read_arguments[MAX_PATH] = {0};
-  char16 read_description[MAX_PATH] = {0};
-  char16 read_icon[MAX_PATH] = {0};
+  wchar_t read_target[MAX_PATH] = {0};
+  wchar_t read_working_dir[MAX_PATH] = {0};
+  wchar_t read_arguments[MAX_PATH] = {0};
+  wchar_t read_description[MAX_PATH] = {0};
+  wchar_t read_icon[MAX_PATH] = {0};
   int read_icon_index = 0;
 
   HRESULT hr;
@@ -84,33 +82,36 @@
     return;
 
   if (properties.options & ShortcutProperties::PROPERTIES_TARGET) {
-    EXPECT_TRUE(SUCCEEDED(i_shell_link->GetPath(
-        as_writable_wcstr(read_target), MAX_PATH, NULL, SLGP_SHORTPATH)));
-    ValidatePathsAreEqual(properties.target, FilePath(read_target));
+    EXPECT_TRUE(SUCCEEDED(
+        i_shell_link->GetPath(read_target, MAX_PATH, NULL, SLGP_SHORTPATH)));
+    ValidatePathsAreEqual(properties.target,
+                          FilePath(AsStringPiece16(read_target)));
   }
 
   if (properties.options & ShortcutProperties::PROPERTIES_WORKING_DIR) {
-    EXPECT_TRUE(SUCCEEDED(i_shell_link->GetWorkingDirectory(
-        as_writable_wcstr(read_working_dir), MAX_PATH)));
-    ValidatePathsAreEqual(properties.working_dir, FilePath(read_working_dir));
+    EXPECT_TRUE(SUCCEEDED(
+        i_shell_link->GetWorkingDirectory(read_working_dir, MAX_PATH)));
+    ValidatePathsAreEqual(properties.working_dir,
+                          FilePath(AsStringPiece16(read_working_dir)));
   }
 
   if (properties.options & ShortcutProperties::PROPERTIES_ARGUMENTS) {
-    EXPECT_TRUE(SUCCEEDED(i_shell_link->GetArguments(
-        as_writable_wcstr(read_arguments), MAX_PATH)));
+    EXPECT_TRUE(
+        SUCCEEDED(i_shell_link->GetArguments(read_arguments, MAX_PATH)));
     EXPECT_EQ(properties.arguments, read_arguments);
   }
 
   if (properties.options & ShortcutProperties::PROPERTIES_DESCRIPTION) {
-    EXPECT_TRUE(SUCCEEDED(i_shell_link->GetDescription(
-        as_writable_wcstr(read_description), MAX_PATH)));
+    EXPECT_TRUE(
+        SUCCEEDED(i_shell_link->GetDescription(read_description, MAX_PATH)));
     EXPECT_EQ(properties.description, read_description);
   }
 
   if (properties.options & ShortcutProperties::PROPERTIES_ICON) {
-    EXPECT_TRUE(SUCCEEDED(i_shell_link->GetIconLocation(
-        as_writable_wcstr(read_icon), MAX_PATH, &read_icon_index)));
-    ValidatePathsAreEqual(properties.icon, FilePath(read_icon));
+    EXPECT_TRUE(SUCCEEDED(
+        i_shell_link->GetIconLocation(read_icon, MAX_PATH, &read_icon_index)));
+    ValidatePathsAreEqual(properties.icon,
+                          FilePath(AsStringPiece16(read_icon)));
     EXPECT_EQ(properties.icon_index, read_icon_index);
   }
 
@@ -129,7 +130,7 @@
         EXPECT_TRUE(properties.app_id.empty());
         break;
       case VT_LPWSTR:
-        EXPECT_EQ(properties.app_id, WideToUTF16(pv_app_id.get().pwszVal));
+        EXPECT_EQ(properties.app_id, pv_app_id.get().pwszVal);
         break;
       default:
         ADD_FAILURE() << "Unexpected variant type: " << pv_app_id.get().vt;
diff --git a/base/time/time_win_unittest.cc b/base/time/time_win_unittest.cc
index 7460bd1..a21b982 100644
--- a/base/time/time_win_unittest.cc
+++ b/base/time/time_win_unittest.cc
@@ -259,13 +259,11 @@
     // Read the CPU frequency from the registry.
     base::win::RegKey processor_key(
         HKEY_LOCAL_MACHINE,
-        STRING16_LITERAL("Hardware\\Description\\System\\CentralProcessor\\0"),
-        KEY_QUERY_VALUE);
+        L"Hardware\\Description\\System\\CentralProcessor\\0", KEY_QUERY_VALUE);
     ASSERT_TRUE(processor_key.Valid());
     DWORD processor_mhz_from_registry;
     ASSERT_EQ(ERROR_SUCCESS,
-              processor_key.ReadValueDW(STRING16_LITERAL("~MHz"),
-                                        &processor_mhz_from_registry));
+              processor_key.ReadValueDW(L"~MHz", &processor_mhz_from_registry));
 
     // Expect the measured TSC frequency to be similar to the processor
     // frequency from the registry (0.5% error).
diff --git a/base/win/embedded_i18n/language_selector.cc b/base/win/embedded_i18n/language_selector.cc
index 1a3a8a79..762b371 100644
--- a/base/win/embedded_i18n/language_selector.cc
+++ b/base/win/embedded_i18n/language_selector.cc
@@ -44,13 +44,13 @@
 
 #if DCHECK_IS_ON()
 // Returns true if the items in the given range are sorted and lower cased.
-bool IsArraySortedAndLowerCased(
-    base::span<const LangToOffset> languages_to_offset) {
+bool IsArraySortedAndLowerCased(span<const LangToOffset> languages_to_offset) {
   return std::is_sorted(languages_to_offset.begin(),
                         languages_to_offset.end()) &&
          std::all_of(languages_to_offset.begin(), languages_to_offset.end(),
                      [](const auto& lang) {
-                       return base::ToLowerASCII(lang.first) == lang.first;
+                       auto language = AsStringPiece16(lang.first);
+                       return ToLowerASCII(language) == language;
                      });
 }
 #endif  // DCHECK_IS_ON()
@@ -58,29 +58,29 @@
 // Determines the availability of all languages that may be used as aliases in
 // GetAliasedLanguageOffset or GetCompatibleNeutralLanguageOffset
 AvailableLanguageAliases DetermineAvailableAliases(
-    base::span<const LangToOffset> languages_to_offset) {
+    span<const LangToOffset> languages_to_offset) {
   AvailableLanguageAliases available_aliases = {};
 
   for (const LangToOffset& lang_to_offset : languages_to_offset) {
-    if (lang_to_offset.first == STRING16_LITERAL("en-gb"))
+    if (lang_to_offset.first == L"en-gb")
       available_aliases.en_gb_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("en-us"))
+    else if (lang_to_offset.first == L"en-us")
       available_aliases.en_us_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("es"))
+    else if (lang_to_offset.first == L"es")
       available_aliases.es_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("es-419"))
+    else if (lang_to_offset.first == L"es-419")
       available_aliases.es_419_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("fil"))
+    else if (lang_to_offset.first == L"fil")
       available_aliases.fil_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("iw"))
+    else if (lang_to_offset.first == L"iw")
       available_aliases.iw_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("no"))
+    else if (lang_to_offset.first == L"no")
       available_aliases.no_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("pt-br"))
+    else if (lang_to_offset.first == L"pt-br")
       available_aliases.pt_br_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("zh-cn"))
+    else if (lang_to_offset.first == L"zh-cn")
       available_aliases.zh_cn_language_offset = &lang_to_offset;
-    else if (lang_to_offset.first == STRING16_LITERAL("zh-tw"))
+    else if (lang_to_offset.first == L"zh-tw")
       available_aliases.zh_tw_language_offset = &lang_to_offset;
   }
 
@@ -93,8 +93,8 @@
 // that matches the |language| exactly. |offset| will store the offset of the
 // language that matches if any. |languages_to_offset| must be sorted by
 // language and all languages must lower case.
-bool GetExactLanguageOffset(base::span<const LangToOffset> languages_to_offset,
-                            const base::string16& language,
+bool GetExactLanguageOffset(span<const LangToOffset> languages_to_offset,
+                            const std::wstring& language,
                             const LangToOffset** matched_language_to_offset) {
   DCHECK(matched_language_to_offset);
 
@@ -102,7 +102,7 @@
   // to a given language |name|.
   auto search_result = std::lower_bound(
       languages_to_offset.begin(), languages_to_offset.end(), language,
-      [](const LangToOffset& left, const base::string16& to_find) {
+      [](const LangToOffset& left, const std::wstring& to_find) {
         return left.first < to_find;
       });
   if (languages_to_offset.end() != search_result &&
@@ -115,65 +115,58 @@
 
 // Returns true if the current language can be aliased to another language.
 bool GetAliasedLanguageOffset(const AvailableLanguageAliases& available_aliases,
-                              const base::string16& language,
+                              const std::wstring& language,
                               const LangToOffset** matched_language_to_offset) {
   DCHECK(matched_language_to_offset);
 
   // Alias some English variants to British English (all others wildcard to
   // US).
   if (available_aliases.en_gb_language_offset &&
-      (language == STRING16_LITERAL("en-au") ||
-       language == STRING16_LITERAL("en-ca") ||
-       language == STRING16_LITERAL("en-nz") ||
-       language == STRING16_LITERAL("en-za"))) {
+      (language == L"en-au" || language == L"en-ca" || language == L"en-nz" ||
+       language == L"en-za")) {
     *matched_language_to_offset = available_aliases.en_gb_language_offset;
     return true;
   }
   // Alias es-es to es (all others wildcard to es-419).
-  if (available_aliases.es_language_offset &&
-      language == STRING16_LITERAL("es-es")) {
+  if (available_aliases.es_language_offset && language == L"es-es") {
     *matched_language_to_offset = available_aliases.es_language_offset;
     return true;
   }
   // Google web properties use iw for he. Handle both just to be safe.
-  if (available_aliases.iw_language_offset &&
-      language == STRING16_LITERAL("he")) {
+  if (available_aliases.iw_language_offset && language == L"he") {
     *matched_language_to_offset = available_aliases.iw_language_offset;
     return true;
   }
   // Google web properties use no for nb. Handle both just to be safe.
-  if (available_aliases.no_language_offset &&
-      language == STRING16_LITERAL("nb")) {
+  if (available_aliases.no_language_offset && language == L"nb") {
     *matched_language_to_offset = available_aliases.no_language_offset;
     return true;
   }
   // Some Google web properties use tl for fil. Handle both just to be safe.
   // They're not completely identical, but alias it here.
-  if (available_aliases.fil_language_offset &&
-      language == STRING16_LITERAL("tl")) {
+  if (available_aliases.fil_language_offset && language == L"tl") {
     *matched_language_to_offset = available_aliases.fil_language_offset;
     return true;
   }
   if (available_aliases.zh_cn_language_offset &&
       // Pre-Vista alias for Chinese w/ script subtag.
-      (language == STRING16_LITERAL("zh-chs") ||
+      (language == L"zh-chs" ||
        // Vista+ alias for Chinese w/ script subtag.
-       language == STRING16_LITERAL("zh-hans") ||
+       language == L"zh-hans" ||
        // Although the wildcard entry for zh would result in this, alias zh-sg
        // so that it will win if it precedes another valid tag in a list of
        // candidates.
-       language == STRING16_LITERAL("zh-sg"))) {
+       language == L"zh-sg")) {
     *matched_language_to_offset = available_aliases.zh_cn_language_offset;
     return true;
   }
   if (available_aliases.zh_tw_language_offset &&
       // Pre-Vista alias for Chinese w/ script subtag.
-      (language == STRING16_LITERAL("zh-cht") ||
+      (language == L"zh-cht" ||
        // Vista+ alias for Chinese w/ script subtag.
-       language == STRING16_LITERAL("zh-hant") ||
+       language == L"zh-hant" ||
        // Alias Hong Kong and Macau to Taiwan.
-       language == STRING16_LITERAL("zh-hk") ||
-       language == STRING16_LITERAL("zh-mo"))) {
+       language == L"zh-hk" || language == L"zh-mo")) {
     *matched_language_to_offset = available_aliases.zh_tw_language_offset;
     return true;
   }
@@ -185,30 +178,26 @@
 // language.
 bool GetCompatibleNeutralLanguageOffset(
     const AvailableLanguageAliases& available_aliases,
-    const base::string16& neutral_language,
+    const std::wstring& neutral_language,
     const LangToOffset** matched_language_to_offset) {
   DCHECK(matched_language_to_offset);
 
-  if (available_aliases.en_us_language_offset &&
-      neutral_language == STRING16_LITERAL("en")) {
+  if (available_aliases.en_us_language_offset && neutral_language == L"en") {
     // Use the U.S. region for anything English.
     *matched_language_to_offset = available_aliases.en_us_language_offset;
     return true;
   }
-  if (available_aliases.es_419_language_offset &&
-      neutral_language == STRING16_LITERAL("es")) {
+  if (available_aliases.es_419_language_offset && neutral_language == L"es") {
     // Use the Latin American region for anything Spanish.
     *matched_language_to_offset = available_aliases.es_419_language_offset;
     return true;
   }
-  if (available_aliases.pt_br_language_offset &&
-      neutral_language == STRING16_LITERAL("pt")) {
+  if (available_aliases.pt_br_language_offset && neutral_language == L"pt") {
     // Use the Brazil region for anything Portugese.
     *matched_language_to_offset = available_aliases.pt_br_language_offset;
     return true;
   }
-  if (available_aliases.zh_cn_language_offset &&
-      neutral_language == STRING16_LITERAL("zh")) {
+  if (available_aliases.zh_cn_language_offset && neutral_language == L"zh") {
     // Use the P.R.C. region for anything Chinese.
     *matched_language_to_offset = available_aliases.zh_cn_language_offset;
     return true;
@@ -223,11 +212,11 @@
 // candidate and |matched_offset| is assigned the language offset of the
 // selected translation.
 // static
-bool SelectIf(const std::vector<base::string16>& candidates,
-              base::span<const LangToOffset> languages_to_offset,
+bool SelectIf(const std::vector<std::wstring>& candidates,
+              span<const LangToOffset> languages_to_offset,
               const AvailableLanguageAliases& available_aliases,
               const LangToOffset** matched_language_to_offset,
-              base::string16* matched_name) {
+              std::wstring* matched_name) {
   DCHECK(matched_language_to_offset);
   DCHECK(matched_name);
 
@@ -236,8 +225,9 @@
 
   // An earlier candidate entry matching on an exact match or alias match takes
   // precedence over a later candidate entry matching on an exact match.
-  for (const base::string16& scan : candidates) {
-    base::string16 lower_case_candidate = base::ToLowerASCII(scan);
+  for (const std::wstring& scan : candidates) {
+    std::wstring lower_case_candidate =
+        AsWString(ToLowerASCII(AsStringPiece16(scan)));
     if (GetExactLanguageOffset(languages_to_offset, lower_case_candidate,
                                matched_language_to_offset) ||
         GetAliasedLanguageOffset(available_aliases, lower_case_candidate,
@@ -249,12 +239,13 @@
 
   // If no candidate matches exactly or by alias, try to match by locale neutral
   // language.
-  for (const base::string16& scan : candidates) {
-    base::string16 lower_case_candidate = base::ToLowerASCII(scan);
+  for (const std::wstring& scan : candidates) {
+    std::wstring lower_case_candidate =
+        AsWString(ToLowerASCII(AsStringPiece16(scan)));
 
     // Extract the locale neutral language from the language to search and try
     // to find an exact match for that language in the provided table.
-    base::string16 neutral_language =
+    std::wstring neutral_language =
         lower_case_candidate.substr(0, lower_case_candidate.find(L'-'));
 
     if (GetCompatibleNeutralLanguageOffset(available_aliases, neutral_language,
@@ -268,11 +259,11 @@
 }
 
 void SelectLanguageMatchingCandidate(
-    const std::vector<base::string16>& candidates,
-    base::span<const LangToOffset> languages_to_offset,
+    const std::vector<std::wstring>& candidates,
+    span<const LangToOffset> languages_to_offset,
     int* selected_offset,
-    base::string16* matched_candidate,
-    base::string16* selected_language) {
+    std::wstring* matched_candidate,
+    std::wstring* selected_language) {
   DCHECK(selected_offset);
   DCHECK(matched_candidate);
   DCHECK(selected_language);
@@ -303,18 +294,18 @@
                 &matched_language_to_offset, matched_candidate)) {
     matched_language_to_offset = available_aliases.en_us_language_offset;
     *matched_candidate =
-        base::string16(available_aliases.en_us_language_offset->first);
+        std::wstring(available_aliases.en_us_language_offset->first);
   }
 
   DCHECK(matched_language_to_offset);
   // Get the real language being used for the matched candidate.
-  *selected_language = base::string16(matched_language_to_offset->first);
+  *selected_language = std::wstring(matched_language_to_offset->first);
   *selected_offset = matched_language_to_offset->second;
 }
 
-std::vector<base::string16> GetCandidatesFromSystem(
-    base::StringPiece16 preferred_language) {
-  std::vector<base::string16> candidates;
+std::vector<std::wstring> GetCandidatesFromSystem(
+    WStringPiece preferred_language) {
+  std::vector<std::wstring> candidates;
 
   // Get the intitial candidate list for this particular implementation (if
   // applicable).
@@ -323,21 +314,19 @@
 
   // Now try the UI languages.  Use the thread preferred ones since that will
   // kindly return us a list of all kinds of fallbacks.
-  base::win::i18n::GetThreadPreferredUILanguageList(&candidates);
+  win::i18n::GetThreadPreferredUILanguageList(&candidates);
   return candidates;
 }
 
 }  // namespace
 
-LanguageSelector::LanguageSelector(
-    base::StringPiece16 preferred_language,
-    base::span<const LangToOffset> languages_to_offset)
+LanguageSelector::LanguageSelector(WStringPiece preferred_language,
+                                   span<const LangToOffset> languages_to_offset)
     : LanguageSelector(GetCandidatesFromSystem(preferred_language),
                        languages_to_offset) {}
 
-LanguageSelector::LanguageSelector(
-    const std::vector<base::string16>& candidates,
-    base::span<const LangToOffset> languages_to_offset)
+LanguageSelector::LanguageSelector(const std::vector<std::wstring>& candidates,
+                                   span<const LangToOffset> languages_to_offset)
     : selected_offset_(languages_to_offset.size()) {
   SelectLanguageMatchingCandidate(candidates, languages_to_offset,
                                   &selected_offset_, &matched_candidate_,
diff --git a/base/win/embedded_i18n/language_selector.h b/base/win/embedded_i18n/language_selector.h
index 2772aee..84d1e9cd 100644
--- a/base/win/embedded_i18n/language_selector.h
+++ b/base/win/embedded_i18n/language_selector.h
@@ -8,13 +8,13 @@
 #ifndef BASE_WIN_EMBEDDED_I18N_LANGUAGE_SELECTOR_H_
 #define BASE_WIN_EMBEDDED_I18N_LANGUAGE_SELECTOR_H_
 
+#include <string>
 #include <utility>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/macros.h"
-#include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 
 namespace base {
@@ -26,7 +26,7 @@
 // override selection should a corresponding translation be available.
 class BASE_EXPORT LanguageSelector {
  public:
-  using LangToOffset = std::pair<base::StringPiece16, int>;
+  using LangToOffset = std::pair<WStringPiece, int>;
 
   // Constructor to be used for users of this class that will provide the actual
   // language offsets that will be used.
@@ -36,8 +36,8 @@
   // |languages_to_offset_begin| and |languages_to_offset_end| point to a sorted
   // array of language identifiers (and their offsets) for which translations
   // are available.
-  LanguageSelector(base::StringPiece16 preferred_language,
-                   base::span<const LangToOffset> languages_to_offset);
+  LanguageSelector(WStringPiece preferred_language,
+                   span<const LangToOffset> languages_to_offset);
 
   // Constructor for testing purposes.
   // |candidates| is a list of all candiate languages that can be used to
@@ -45,8 +45,8 @@
   // |languages_to_offset_begin| and |languages_to_offset_end| point to a sorted
   // array of language identifiers (and their offsets) for which translations
   // are available.
-  LanguageSelector(const std::vector<base::string16>& candidates,
-                   base::span<const LangToOffset> languages_to_offset);
+  LanguageSelector(const std::vector<std::wstring>& candidates,
+                   span<const LangToOffset> languages_to_offset);
 
   ~LanguageSelector();
 
@@ -54,16 +54,16 @@
   int offset() const { return selected_offset_; }
 
   // The full name of the candidate language for which a match was found.
-  const base::string16& matched_candidate() const { return matched_candidate_; }
+  const std::wstring& matched_candidate() const { return matched_candidate_; }
 
   // The name of the selected translation.
-  const base::string16& selected_translation() const {
+  const std::wstring& selected_translation() const {
     return selected_language_;
   }
 
  private:
-  base::string16 matched_candidate_;
-  base::string16 selected_language_;
+  std::wstring matched_candidate_;
+  std::wstring selected_language_;
   int selected_offset_;
 
   DISALLOW_COPY_AND_ASSIGN(LanguageSelector);
diff --git a/base/win/embedded_i18n/language_selector_unittest.cc b/base/win/embedded_i18n/language_selector_unittest.cc
index 64efc1d..6903d0c 100644
--- a/base/win/embedded_i18n/language_selector_unittest.cc
+++ b/base/win/embedded_i18n/language_selector_unittest.cc
@@ -17,49 +17,26 @@
 namespace i18n {
 namespace {
 
-constexpr const base::char16* kExactMatchCandidates[] = {
-    STRING16_LITERAL("am"),     STRING16_LITERAL("ar"),
-    STRING16_LITERAL("bg"),     STRING16_LITERAL("bn"),
-    STRING16_LITERAL("ca"),     STRING16_LITERAL("cs"),
-    STRING16_LITERAL("da"),     STRING16_LITERAL("de"),
-    STRING16_LITERAL("el"),     STRING16_LITERAL("en-gb"),
-    STRING16_LITERAL("en-us"),  STRING16_LITERAL("es"),
-    STRING16_LITERAL("es-419"), STRING16_LITERAL("et"),
-    STRING16_LITERAL("fa"),     STRING16_LITERAL("fi"),
-    STRING16_LITERAL("fil"),    STRING16_LITERAL("fr"),
-    STRING16_LITERAL("gu"),     STRING16_LITERAL("hi"),
-    STRING16_LITERAL("hr"),     STRING16_LITERAL("hu"),
-    STRING16_LITERAL("id"),     STRING16_LITERAL("it"),
-    STRING16_LITERAL("iw"),     STRING16_LITERAL("ja"),
-    STRING16_LITERAL("kn"),     STRING16_LITERAL("ko"),
-    STRING16_LITERAL("lt"),     STRING16_LITERAL("lv"),
-    STRING16_LITERAL("ml"),     STRING16_LITERAL("mr"),
-    STRING16_LITERAL("nl"),     STRING16_LITERAL("no"),
-    STRING16_LITERAL("pl"),     STRING16_LITERAL("pt-br"),
-    STRING16_LITERAL("pt-pt"),  STRING16_LITERAL("ro"),
-    STRING16_LITERAL("ru"),     STRING16_LITERAL("sk"),
-    STRING16_LITERAL("sl"),     STRING16_LITERAL("sr"),
-    STRING16_LITERAL("sv"),     STRING16_LITERAL("sw"),
-    STRING16_LITERAL("ta"),     STRING16_LITERAL("te"),
-    STRING16_LITERAL("th"),     STRING16_LITERAL("tr"),
-    STRING16_LITERAL("uk"),     STRING16_LITERAL("vi"),
-    STRING16_LITERAL("zh-cn"),  STRING16_LITERAL("zh-tw")};
+constexpr const wchar_t* kExactMatchCandidates[] = {
+    L"am",  L"ar",    L"bg",    L"bn",    L"ca",     L"cs", L"da", L"de",
+    L"el",  L"en-gb", L"en-us", L"es",    L"es-419", L"et", L"fa", L"fi",
+    L"fil", L"fr",    L"gu",    L"hi",    L"hr",     L"hu", L"id", L"it",
+    L"iw",  L"ja",    L"kn",    L"ko",    L"lt",     L"lv", L"ml", L"mr",
+    L"nl",  L"no",    L"pl",    L"pt-br", L"pt-pt",  L"ro", L"ru", L"sk",
+    L"sl",  L"sr",    L"sv",    L"sw",    L"ta",     L"te", L"th", L"tr",
+    L"uk",  L"vi",    L"zh-cn", L"zh-tw"};
 
-constexpr const base::char16* kAliasMatchCandidates[] = {
-    STRING16_LITERAL("he"),      STRING16_LITERAL("nb"),
-    STRING16_LITERAL("tl"),      STRING16_LITERAL("zh-chs"),
-    STRING16_LITERAL("zh-cht"),  STRING16_LITERAL("zh-hans"),
-    STRING16_LITERAL("zh-hant"), STRING16_LITERAL("zh-hk"),
-    STRING16_LITERAL("zh-mo")};
+constexpr const wchar_t* kAliasMatchCandidates[] = {
+    L"he",      L"nb",      L"tl",    L"zh-chs", L"zh-cht",
+    L"zh-hans", L"zh-hant", L"zh-hk", L"zh-mo"};
 
-constexpr const base::char16* kWildcardMatchCandidates[] = {
-    STRING16_LITERAL("en-AU"), STRING16_LITERAL("es-CO"),
-    STRING16_LITERAL("pt-AB"), STRING16_LITERAL("zh-SG")};
+constexpr const wchar_t* kWildcardMatchCandidates[] = {L"en-AU", L"es-CO",
+                                                       L"pt-AB", L"zh-SG"};
 
 std::vector<LanguageSelector::LangToOffset> MakeLanguageOffsetPairs() {
   std::vector<LanguageSelector::LangToOffset> language_offset_pairs;
   int i = 0;
-  for (const base::char16* lang : kExactMatchCandidates) {
+  for (const wchar_t* lang : kExactMatchCandidates) {
     language_offset_pairs.push_back({lang, i++});
   }
 
@@ -68,13 +45,12 @@
 
 class TestLanguageSelector : public LanguageSelector {
  public:
-  TestLanguageSelector()
-      : TestLanguageSelector(std::vector<base::string16>()) {}
-  explicit TestLanguageSelector(const std::vector<base::string16>& candidates)
+  TestLanguageSelector() : TestLanguageSelector(std::vector<std::wstring>()) {}
+  explicit TestLanguageSelector(const std::vector<std::wstring>& candidates)
       : TestLanguageSelector(candidates, MakeLanguageOffsetPairs()) {}
   TestLanguageSelector(
-      const std::vector<base::string16>& candidates,
-      base::span<const LanguageSelector::LangToOffset> languages_to_offset)
+      const std::vector<std::wstring>& candidates,
+      span<const LanguageSelector::LangToOffset> languages_to_offset)
       : LanguageSelector(candidates, languages_to_offset) {}
 };
 
@@ -89,32 +65,28 @@
 // Test some hypothetical candidate sets.
 TEST(LanguageSelectorTest, AssortedSelections) {
   {
-    std::vector<base::string16> candidates = {STRING16_LITERAL("fr-BE"),
-                                              STRING16_LITERAL("fr"),
-                                              STRING16_LITERAL("en")};
+    std::vector<std::wstring> candidates = {L"fr-BE", L"fr", L"en"};
     TestLanguageSelector instance(candidates);
     // Expect the exact match to win.
-    EXPECT_EQ(STRING16_LITERAL("fr"), instance.matched_candidate());
+    EXPECT_EQ(L"fr", instance.matched_candidate());
   }
   {
-    std::vector<base::string16> candidates = {STRING16_LITERAL("xx-YY"),
-                                              STRING16_LITERAL("cc-Ssss-RR")};
+    std::vector<std::wstring> candidates = {L"xx-YY", L"cc-Ssss-RR"};
     TestLanguageSelector instance(candidates);
     // Expect the fallback to win.
-    EXPECT_EQ(STRING16_LITERAL("en-us"), instance.matched_candidate());
+    EXPECT_EQ(L"en-us", instance.matched_candidate());
   }
   {
-    std::vector<base::string16> candidates = {STRING16_LITERAL("zh-SG"),
-                                              STRING16_LITERAL("en-GB")};
+    std::vector<std::wstring> candidates = {L"zh-SG", L"en-GB"};
     TestLanguageSelector instance(candidates);
     // Expect the alias match to win.
-    EXPECT_EQ(STRING16_LITERAL("zh-SG"), instance.matched_candidate());
+    EXPECT_EQ(L"zh-SG", instance.matched_candidate());
   }
 }
 
 // A fixture for testing sets of single-candidate selections.
 class LanguageSelectorMatchCandidateTest
-    : public ::testing::TestWithParam<const base::char16*> {};
+    : public ::testing::TestWithParam<const wchar_t*> {};
 
 TEST_P(LanguageSelectorMatchCandidateTest, TestMatchCandidate) {
   TestLanguageSelector instance({GetParam()});
@@ -141,7 +113,7 @@
 // candidate that should be aliased to the expectation.
 class LanguageSelectorAliasTest
     : public ::testing::TestWithParam<
-          std::tuple<const base::char16*, const base::char16*>> {};
+          std::tuple<const wchar_t*, const wchar_t*>> {};
 
 // Test that the candidate language maps to the aliased translation.
 TEST_P(LanguageSelectorAliasTest, AliasesMatch) {
@@ -149,49 +121,42 @@
   EXPECT_EQ(std::get<0>(GetParam()), instance.selected_translation());
 }
 
-INSTANTIATE_TEST_SUITE_P(
-    EnGbAliases,
-    LanguageSelectorAliasTest,
-    ::testing::Combine(::testing::Values(STRING16_LITERAL("en-gb")),
-                       ::testing::Values(STRING16_LITERAL("en-au"),
-                                         STRING16_LITERAL("en-ca"),
-                                         STRING16_LITERAL("en-nz"),
-                                         STRING16_LITERAL("en-za"))));
+INSTANTIATE_TEST_SUITE_P(EnGbAliases,
+                         LanguageSelectorAliasTest,
+                         ::testing::Combine(::testing::Values(L"en-gb"),
+                                            ::testing::Values(L"en-au",
+                                                              L"en-ca",
+                                                              L"en-nz",
+                                                              L"en-za")));
 
-INSTANTIATE_TEST_SUITE_P(
-    IwAliases,
-    LanguageSelectorAliasTest,
-    ::testing::Combine(::testing::Values(STRING16_LITERAL("iw")),
-                       ::testing::Values(STRING16_LITERAL("he"))));
+INSTANTIATE_TEST_SUITE_P(IwAliases,
+                         LanguageSelectorAliasTest,
+                         ::testing::Combine(::testing::Values(L"iw"),
+                                            ::testing::Values(L"he")));
 
-INSTANTIATE_TEST_SUITE_P(
-    NoAliases,
-    LanguageSelectorAliasTest,
-    ::testing::Combine(::testing::Values(STRING16_LITERAL("no")),
-                       ::testing::Values(STRING16_LITERAL("nb"))));
+INSTANTIATE_TEST_SUITE_P(NoAliases,
+                         LanguageSelectorAliasTest,
+                         ::testing::Combine(::testing::Values(L"no"),
+                                            ::testing::Values(L"nb")));
 
-INSTANTIATE_TEST_SUITE_P(
-    FilAliases,
-    LanguageSelectorAliasTest,
-    ::testing::Combine(::testing::Values(STRING16_LITERAL("fil")),
-                       ::testing::Values(STRING16_LITERAL("tl"))));
+INSTANTIATE_TEST_SUITE_P(FilAliases,
+                         LanguageSelectorAliasTest,
+                         ::testing::Combine(::testing::Values(L"fil"),
+                                            ::testing::Values(L"tl")));
 
 INSTANTIATE_TEST_SUITE_P(
     ZhCnAliases,
     LanguageSelectorAliasTest,
-    ::testing::Combine(::testing::Values(STRING16_LITERAL("zh-cn")),
-                       ::testing::Values(STRING16_LITERAL("zh-chs"),
-                                         STRING16_LITERAL("zh-hans"),
-                                         STRING16_LITERAL("zh-sg"))));
+    ::testing::Combine(::testing::Values(L"zh-cn"),
+                       ::testing::Values(L"zh-chs", L"zh-hans", L"zh-sg")));
 
-INSTANTIATE_TEST_SUITE_P(
-    ZhTwAliases,
-    LanguageSelectorAliasTest,
-    ::testing::Combine(::testing::Values(STRING16_LITERAL("zh-tw")),
-                       ::testing::Values(STRING16_LITERAL("zh-cht"),
-                                         STRING16_LITERAL("zh-hant"),
-                                         STRING16_LITERAL("zh-hk"),
-                                         STRING16_LITERAL("zh-mo"))));
+INSTANTIATE_TEST_SUITE_P(ZhTwAliases,
+                         LanguageSelectorAliasTest,
+                         ::testing::Combine(::testing::Values(L"zh-tw"),
+                                            ::testing::Values(L"zh-cht",
+                                                              L"zh-hant",
+                                                              L"zh-hk",
+                                                              L"zh-mo")));
 
 // Test that we can get a match of the default language.
 TEST(LanguageSelectorTest, DefaultLanguageName) {
@@ -202,34 +167,32 @@
 // All languages given to the selector must be lower cased (since generally
 // the language names are generated by a python script).
 TEST(LanguageSelectorTest, InvalidLanguageCasing) {
-  constexpr LanguageSelector::LangToOffset kLangToOffset[] = {
-      {STRING16_LITERAL("en-US"), 0}};
+  constexpr LanguageSelector::LangToOffset kLangToOffset[] = {{L"en-US", 0}};
   EXPECT_DCHECK_DEATH(LanguageSelector instance(
-      std::vector<base::string16>({STRING16_LITERAL("en-us")}), kLangToOffset));
+      std::vector<std::wstring>({L"en-us"}), kLangToOffset));
 }
 
 // Language name and offset pairs must be ordered when generated by the
 // python script.
 TEST(LanguageSelectorTest, InvalidLanguageNameOrder) {
-  constexpr LanguageSelector::LangToOffset kLangToOffset[] = {
-      {STRING16_LITERAL("en-us"), 0}, {STRING16_LITERAL("en-gb"), 1}};
+  constexpr LanguageSelector::LangToOffset kLangToOffset[] = {{L"en-us", 0},
+                                                              {L"en-gb", 1}};
   EXPECT_DCHECK_DEATH(LanguageSelector instance(
-      std::vector<base::string16>({STRING16_LITERAL("en-us")}), kLangToOffset));
+      std::vector<std::wstring>({L"en-us"}), kLangToOffset));
 }
 
 // There needs to be a fallback language available in the generated
 // languages if ever the selector is given a language that does not exist.
 TEST(LanguageSelectorTest, NoFallbackLanguageAvailable) {
-  constexpr LanguageSelector::LangToOffset kLangToOffset[] = {
-      {STRING16_LITERAL("en-gb"), 0}};
+  constexpr LanguageSelector::LangToOffset kLangToOffset[] = {{L"en-gb", 0}};
   EXPECT_DCHECK_DEATH(LanguageSelector instance(
-      std::vector<base::string16>({STRING16_LITERAL("aa-bb")}), kLangToOffset));
+      std::vector<std::wstring>({L"aa-bb"}), kLangToOffset));
 }
 
 // No languages available.
 TEST(LanguageSelectorTest, NoLanguagesAvailable) {
-  EXPECT_DCHECK_DEATH(LanguageSelector instance(
-      std::vector<base::string16>({STRING16_LITERAL("en-us")}), {}));
+  EXPECT_DCHECK_DEATH(
+      LanguageSelector instance(std::vector<std::wstring>({L"en-us"}), {}));
 }
 
 }  // namespace i18n
diff --git a/base/win/i18n.cc b/base/win/i18n.cc
index adba36d..ca80f938 100644
--- a/base/win/i18n.cc
+++ b/base/win/i18n.cc
@@ -16,7 +16,7 @@
 
 bool GetPreferredUILanguageList(GetPreferredUILanguages_Fn function,
                                 ULONG flags,
-                                std::vector<base::string16>* languages) {
+                                std::vector<std::wstring>* languages) {
   DCHECK_EQ((flags & (MUI_LANGUAGE_ID | MUI_LANGUAGE_NAME)), 0U);
   const ULONG call_flags = flags | MUI_LANGUAGE_NAME;
   ULONG language_count = 0;
@@ -27,18 +27,21 @@
     return false;
   }
 
-  base::string16 buffer(buffer_length, '\0');
-  if (!function(call_flags, &language_count, base::as_writable_wcstr(buffer),
+  std::wstring buffer(buffer_length, '\0');
+  if (!function(call_flags, &language_count, base::data(buffer),
                 &buffer_length) ||
       !language_count) {
     DPCHECK(!language_count) << "Failed getting preferred UI languages.";
     return false;
   }
 
+  languages->clear();
   // Split string on NUL characters.
-  *languages =
-      base::SplitString(buffer, base::string16(1, '\0'), base::KEEP_WHITESPACE,
-                        base::SPLIT_WANT_NONEMPTY);
+  for (const auto& token : base::SplitStringPiece(
+           base::AsStringPiece16(buffer), base::string16(1, '\0'),
+           base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
+    languages->push_back(base::AsWString(token));
+  }
   DCHECK_EQ(languages->size(), language_count);
   return true;
 }
@@ -49,13 +52,13 @@
 namespace win {
 namespace i18n {
 
-bool GetUserPreferredUILanguageList(std::vector<base::string16>* languages) {
+bool GetUserPreferredUILanguageList(std::vector<std::wstring>* languages) {
   DCHECK(languages);
   return GetPreferredUILanguageList(::GetUserPreferredUILanguages, 0,
                                     languages);
 }
 
-bool GetThreadPreferredUILanguageList(std::vector<base::string16>* languages) {
+bool GetThreadPreferredUILanguageList(std::vector<std::wstring>* languages) {
   DCHECK(languages);
   return GetPreferredUILanguageList(
       ::GetThreadPreferredUILanguages,
diff --git a/base/win/i18n.h b/base/win/i18n.h
index d586646..9e74d3f 100644
--- a/base/win/i18n.h
+++ b/base/win/i18n.h
@@ -5,10 +5,10 @@
 #ifndef BASE_WIN_I18N_H_
 #define BASE_WIN_I18N_H_
 
+#include <string>
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/strings/string16.h"
 
 namespace base {
 namespace win {
@@ -18,13 +18,13 @@
 // available, falling-back on the user default UI language otherwise.  Returns
 // true if at least one language is added.
 BASE_EXPORT bool GetUserPreferredUILanguageList(
-    std::vector<base::string16>* languages);
+    std::vector<std::wstring>* languages);
 
 // Adds to |languages| the list of thread, process, user, and system preferred
 // UI languages from MUI, if available, falling-back on the user default UI
 // language otherwise.  Returns true if at least one language is added.
 BASE_EXPORT bool GetThreadPreferredUILanguageList(
-    std::vector<base::string16>* languages);
+    std::vector<std::wstring>* languages);
 
 }  // namespace i18n
 }  // namespace win
diff --git a/base/win/i18n_unittest.cc b/base/win/i18n_unittest.cc
index 3b0b668a..f38db24 100644
--- a/base/win/i18n_unittest.cc
+++ b/base/win/i18n_unittest.cc
@@ -19,24 +19,24 @@
 
 // Tests that at least one user preferred UI language can be obtained.
 TEST(I18NTest, GetUserPreferredUILanguageList) {
-  std::vector<base::string16> languages;
+  std::vector<std::wstring> languages;
   EXPECT_TRUE(GetUserPreferredUILanguageList(&languages));
   EXPECT_FALSE(languages.empty());
   for (const auto& language : languages) {
     EXPECT_FALSE(language.empty());
     // Ensure there's no extra trailing 0 characters.
-    EXPECT_EQ(language.size(), wcslen(base::as_wcstr(language)));
+    EXPECT_EQ(language.size(), wcslen(language.c_str()));
   }
 }
 
 // Tests that at least one thread preferred UI language can be obtained.
 TEST(I18NTest, GetThreadPreferredUILanguageList) {
-  std::vector<base::string16> languages;
+  std::vector<std::wstring> languages;
   EXPECT_TRUE(GetThreadPreferredUILanguageList(&languages));
   EXPECT_FALSE(languages.empty());
   for (const auto& language : languages) {
     EXPECT_FALSE(language.empty());
-    EXPECT_EQ(language.size(), wcslen(base::as_wcstr(language)));
+    EXPECT_EQ(language.size(), wcslen(language.c_str()));
   }
 }
 
diff --git a/base/win/registry.cc b/base/win/registry.cc
index b95b4746..cd6208ed 100644
--- a/base/win/registry.cc
+++ b/base/win/registry.cc
@@ -13,6 +13,7 @@
 #include "base/logging.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
+#include "base/strings/string_util_win.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/win/shlwapi.h"
 #include "base/win/windows_version.h"
@@ -95,7 +96,7 @@
 RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) {
 }
 
-RegKey::RegKey(HKEY rootkey, const char16* subkey, REGSAM access)
+RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access)
     : key_(NULL), wow64access_(0) {
   if (rootkey) {
     if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
@@ -112,20 +113,20 @@
   Close();
 }
 
-LONG RegKey::Create(HKEY rootkey, const char16* subkey, REGSAM access) {
+LONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
   DWORD disposition_value;
   return CreateWithDisposition(rootkey, subkey, &disposition_value, access);
 }
 
 LONG RegKey::CreateWithDisposition(HKEY rootkey,
-                                   const char16* subkey,
+                                   const wchar_t* subkey,
                                    DWORD* disposition,
                                    REGSAM access) {
   DCHECK(rootkey && subkey && access && disposition);
   HKEY subhkey = NULL;
-  LONG result = RegCreateKeyEx(rootkey, as_wcstr(subkey), 0, NULL,
-                               REG_OPTION_NON_VOLATILE, access, NULL, &subhkey,
-                               disposition);
+  LONG result =
+      RegCreateKeyEx(rootkey, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, access,
+                     NULL, &subhkey, disposition);
   if (result == ERROR_SUCCESS) {
     Close();
     key_ = subhkey;
@@ -135,7 +136,7 @@
   return result;
 }
 
-LONG RegKey::CreateKey(const char16* name, REGSAM access) {
+LONG RegKey::CreateKey(const wchar_t* name, REGSAM access) {
   DCHECK(name && access);
   // After the application has accessed an alternate registry view using one of
   // the [KEY_WOW64_32KEY / KEY_WOW64_64KEY] flags, all subsequent operations
@@ -147,9 +148,8 @@
     return ERROR_INVALID_PARAMETER;
   }
   HKEY subkey = NULL;
-  LONG result =
-      RegCreateKeyEx(key_, as_wcstr(name), 0, NULL, REG_OPTION_NON_VOLATILE,
-                     access, NULL, &subkey, NULL);
+  LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE,
+                               access, NULL, &subkey, NULL);
   if (result == ERROR_SUCCESS) {
     Close();
     key_ = subkey;
@@ -159,11 +159,11 @@
   return result;
 }
 
-LONG RegKey::Open(HKEY rootkey, const char16* subkey, REGSAM access) {
+LONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
   DCHECK(rootkey && subkey && access);
   HKEY subhkey = NULL;
 
-  LONG result = RegOpenKeyEx(rootkey, as_wcstr(subkey), 0, access, &subhkey);
+  LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &subhkey);
   if (result == ERROR_SUCCESS) {
     Close();
     key_ = subhkey;
@@ -173,7 +173,7 @@
   return result;
 }
 
-LONG RegKey::OpenKey(const char16* relative_key_name, REGSAM access) {
+LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) {
   DCHECK(relative_key_name && access);
   // After the application has accessed an alternate registry view using one of
   // the [KEY_WOW64_32KEY / KEY_WOW64_64KEY] flags, all subsequent operations
@@ -185,8 +185,7 @@
     return ERROR_INVALID_PARAMETER;
   }
   HKEY subkey = NULL;
-  LONG result =
-      RegOpenKeyEx(key_, as_wcstr(relative_key_name), 0, access, &subkey);
+  LONG result = RegOpenKeyEx(key_, relative_key_name, 0, access, &subkey);
 
   // We have to close the current opened key before replacing it with the new
   // one.
@@ -221,9 +220,8 @@
   return key;
 }
 
-bool RegKey::HasValue(const char16* name) const {
-  return RegQueryValueEx(key_, as_wcstr(name), 0, NULL, NULL, NULL) ==
-         ERROR_SUCCESS;
+bool RegKey::HasValue(const wchar_t* name) const {
+  return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS;
 }
 
 DWORD RegKey::GetValueCount() const {
@@ -233,26 +231,25 @@
   return (result == ERROR_SUCCESS) ? count : 0;
 }
 
-LONG RegKey::GetValueNameAt(int index, string16* name) const {
-  char16 buf[256];
+LONG RegKey::GetValueNameAt(int index, std::wstring* name) const {
+  wchar_t buf[256];
   DWORD bufsize = size(buf);
-  LONG r = ::RegEnumValue(key_, index, as_writable_wcstr(buf), &bufsize, NULL,
-                          NULL, NULL, NULL);
+  LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL);
   if (r == ERROR_SUCCESS)
     name->assign(buf, bufsize);
 
   return r;
 }
 
-LONG RegKey::DeleteKey(const char16* name) {
+LONG RegKey::DeleteKey(const wchar_t* name) {
   DCHECK(key_);
   DCHECK(name);
   HKEY subkey = NULL;
 
   // Verify the key exists before attempting delete to replicate previous
   // behavior.
-  LONG result = RegOpenKeyEx(key_, as_wcstr(name), 0,
-                             READ_CONTROL | wow64access_, &subkey);
+  LONG result =
+      RegOpenKeyEx(key_, name, 0, READ_CONTROL | wow64access_, &subkey);
   if (result != ERROR_SUCCESS)
     return result;
   RegCloseKey(subkey);
@@ -260,13 +257,13 @@
   return RegDelRecurse(key_, name, wow64access_);
 }
 
-LONG RegKey::DeleteEmptyKey(const char16* name) {
+LONG RegKey::DeleteEmptyKey(const wchar_t* name) {
   DCHECK(key_);
   DCHECK(name);
 
   HKEY target_key = NULL;
-  LONG result = RegOpenKeyEx(key_, as_wcstr(name), 0, KEY_READ | wow64access_,
-                             &target_key);
+  LONG result =
+      RegOpenKeyEx(key_, name, 0, KEY_READ | wow64access_, &target_key);
 
   if (result != ERROR_SUCCESS)
     return result;
@@ -281,18 +278,18 @@
     return result;
 
   if (count == 0)
-    return RegDeleteKeyEx(key_, as_wcstr(name), wow64access_, 0);
+    return RegDeleteKeyEx(key_, name, wow64access_, 0);
 
   return ERROR_DIR_NOT_EMPTY;
 }
 
-LONG RegKey::DeleteValue(const char16* value_name) {
+LONG RegKey::DeleteValue(const wchar_t* value_name) {
   DCHECK(key_);
-  LONG result = RegDeleteValue(key_, as_wcstr(value_name));
+  LONG result = RegDeleteValue(key_, value_name);
   return result;
 }
 
-LONG RegKey::ReadValueDW(const char16* name, DWORD* out_value) const {
+LONG RegKey::ReadValueDW(const wchar_t* name, DWORD* out_value) const {
   DCHECK(out_value);
   DWORD type = REG_DWORD;
   DWORD size = sizeof(DWORD);
@@ -308,7 +305,7 @@
   return result;
 }
 
-LONG RegKey::ReadInt64(const char16* name, int64_t* out_value) const {
+LONG RegKey::ReadInt64(const wchar_t* name, int64_t* out_value) const {
   DCHECK(out_value);
   DWORD type = REG_QWORD;
   int64_t local_value = 0;
@@ -325,20 +322,19 @@
   return result;
 }
 
-LONG RegKey::ReadValue(const char16* name, string16* out_value) const {
+LONG RegKey::ReadValue(const wchar_t* name, std::wstring* out_value) const {
   DCHECK(out_value);
   const size_t kMaxStringLength = 1024;  // This is after expansion.
   // Use the one of the other forms of ReadValue if 1024 is too small for you.
-  char16 raw_value[kMaxStringLength];
+  wchar_t raw_value[kMaxStringLength];
   DWORD type = REG_SZ, size = sizeof(raw_value);
-  LONG result = ReadValue(name, as_writable_wcstr(raw_value), &size, &type);
+  LONG result = ReadValue(name, raw_value, &size, &type);
   if (result == ERROR_SUCCESS) {
     if (type == REG_SZ) {
       *out_value = raw_value;
     } else if (type == REG_EXPAND_SZ) {
-      char16 expanded[kMaxStringLength];
-      size = ExpandEnvironmentStrings(
-          as_wcstr(raw_value), as_writable_wcstr(expanded), kMaxStringLength);
+      wchar_t expanded[kMaxStringLength];
+      size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength);
       // Success: returns the number of wchar_t's copied
       // Fail: buffer too small, returns the size required
       // Fail: other, returns 0
@@ -356,16 +352,17 @@
   return result;
 }
 
-LONG RegKey::ReadValue(const char16* name,
+LONG RegKey::ReadValue(const wchar_t* name,
                        void* data,
                        DWORD* dsize,
                        DWORD* dtype) const {
-  LONG result = RegQueryValueEx(key_, as_wcstr(name), 0, dtype,
+  LONG result = RegQueryValueEx(key_, name, 0, dtype,
                                 reinterpret_cast<LPBYTE>(data), dsize);
   return result;
 }
 
-LONG RegKey::ReadValues(const char16* name, std::vector<string16>* values) {
+LONG RegKey::ReadValues(const wchar_t* name,
+                        std::vector<std::wstring>* values) {
   values->clear();
 
   DWORD type = REG_MULTI_SZ;
@@ -377,8 +374,8 @@
   if (type != REG_MULTI_SZ)
     return ERROR_CANTREAD;
 
-  std::vector<char16> buffer(size / sizeof(char16));
-  result = ReadValue(name, as_writable_wcstr(buffer.data()), &size, NULL);
+  std::vector<wchar_t> buffer(size / sizeof(wchar_t));
+  result = ReadValue(name, buffer.data(), &size, NULL);
   if (result != ERROR_SUCCESS || size == 0)
     return result;
 
@@ -395,27 +392,27 @@
   return 0;
 }
 
-LONG RegKey::WriteValue(const char16* name, DWORD in_value) {
+LONG RegKey::WriteValue(const wchar_t* name, DWORD in_value) {
   return WriteValue(
       name, &in_value, static_cast<DWORD>(sizeof(in_value)), REG_DWORD);
 }
 
-LONG RegKey::WriteValue(const char16* name, const char16* in_value) {
+LONG RegKey::WriteValue(const wchar_t* name, const wchar_t* in_value) {
   return WriteValue(
       name, in_value,
       static_cast<DWORD>(sizeof(*in_value) *
-                         (std::char_traits<char16>::length(in_value) + 1)),
+                         (std::char_traits<wchar_t>::length(in_value) + 1)),
       REG_SZ);
 }
 
-LONG RegKey::WriteValue(const char16* name,
+LONG RegKey::WriteValue(const wchar_t* name,
                         const void* data,
                         DWORD dsize,
                         DWORD dtype) {
   DCHECK(data || !dsize);
 
   LONG result =
-      RegSetValueEx(key_, as_wcstr(name), 0, dtype,
+      RegSetValueEx(key_, name, 0, dtype,
                     reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize);
   return result;
 }
@@ -431,22 +428,22 @@
 }
 
 // static
-LONG RegKey::RegDelRecurse(HKEY root_key, const char16* name, REGSAM access) {
+LONG RegKey::RegDelRecurse(HKEY root_key, const wchar_t* name, REGSAM access) {
   // First, see if the key can be deleted without having to recurse.
-  LONG result = RegDeleteKeyEx(root_key, as_wcstr(name), access, 0);
+  LONG result = RegDeleteKeyEx(root_key, name, access, 0);
   if (result == ERROR_SUCCESS)
     return result;
 
   HKEY target_key = NULL;
-  result = RegOpenKeyEx(root_key, as_wcstr(name), 0,
-                        KEY_ENUMERATE_SUB_KEYS | access, &target_key);
+  result = RegOpenKeyEx(root_key, name, 0, KEY_ENUMERATE_SUB_KEYS | access,
+                        &target_key);
 
   if (result == ERROR_FILE_NOT_FOUND)
     return ERROR_SUCCESS;
   if (result != ERROR_SUCCESS)
     return result;
 
-  string16 subkey_name(name);
+  std::wstring subkey_name(name);
 
   // Check for an ending slash and add one if it is missing.
   if (!subkey_name.empty() && subkey_name.back() != '\\')
@@ -456,12 +453,11 @@
   result = ERROR_SUCCESS;
   const DWORD kMaxKeyNameLength = MAX_PATH;
   const size_t base_key_length = subkey_name.length();
-  string16 key_name;
+  std::wstring key_name;
   while (result == ERROR_SUCCESS) {
     DWORD key_size = kMaxKeyNameLength;
     result =
-        RegEnumKeyEx(target_key, 0,
-                     as_writable_wcstr(WriteInto(&key_name, kMaxKeyNameLength)),
+        RegEnumKeyEx(target_key, 0, WriteIntoW(&key_name, kMaxKeyNameLength),
                      &key_size, NULL, NULL, NULL, NULL);
 
     if (result != ERROR_SUCCESS)
@@ -478,7 +474,7 @@
   RegCloseKey(target_key);
 
   // Try again to delete the key.
-  result = RegDeleteKeyEx(root_key, as_wcstr(name), access, 0);
+  result = RegDeleteKeyEx(root_key, name, access, 0);
 
   return result;
 }
@@ -486,24 +482,24 @@
 // RegistryValueIterator ------------------------------------------------------
 
 RegistryValueIterator::RegistryValueIterator(HKEY root_key,
-                                             const char16* folder_key,
+                                             const wchar_t* folder_key,
                                              REGSAM wow64access)
     : name_(MAX_PATH, '\0'), value_(MAX_PATH, '\0') {
   Initialize(root_key, folder_key, wow64access);
 }
 
 RegistryValueIterator::RegistryValueIterator(HKEY root_key,
-                                             const char16* folder_key)
+                                             const wchar_t* folder_key)
     : name_(MAX_PATH, '\0'), value_(MAX_PATH, '\0') {
   Initialize(root_key, folder_key, 0);
 }
 
 void RegistryValueIterator::Initialize(HKEY root_key,
-                                       const char16* folder_key,
+                                       const wchar_t* folder_key,
                                        REGSAM wow64access) {
   DCHECK_EQ(wow64access & ~kWow64AccessMask, static_cast<REGSAM>(0));
-  LONG result = RegOpenKeyEx(root_key, as_wcstr(folder_key), 0,
-                             KEY_READ | wow64access, &key_);
+  LONG result =
+      RegOpenKeyEx(root_key, folder_key, 0, KEY_READ | wow64access, &key_);
   if (result != ERROR_SUCCESS) {
     key_ = NULL;
   } else {
@@ -551,13 +547,10 @@
     DWORD capacity = static_cast<DWORD>(name_.capacity());
     DWORD name_size = capacity;
     // |value_size_| is in bytes. Reserve the last character for a NUL.
-    static_assert(sizeof(wchar_t) == sizeof(char16),
-                  "wchar_t is not the same size as base::char16");
     value_size_ = static_cast<DWORD>((value_.size() - 1) * sizeof(wchar_t));
     LONG result = ::RegEnumValue(
-        key_, index_, as_writable_wcstr(WriteInto(&name_, name_size)),
-        &name_size, NULL, &type_, reinterpret_cast<BYTE*>(value_.data()),
-        &value_size_);
+        key_, index_, WriteIntoW(&name_, name_size), &name_size, NULL, &type_,
+        reinterpret_cast<BYTE*>(value_.data()), &value_size_);
 
     if (result == ERROR_MORE_DATA) {
       // Registry key names are limited to 255 characters and fit within
@@ -572,9 +565,8 @@
       value_size_ = static_cast<DWORD>((value_.size() - 1) * sizeof(wchar_t));
       name_size = name_size == capacity ? MAX_REGISTRY_NAME_SIZE : capacity;
       result = ::RegEnumValue(
-          key_, index_, as_writable_wcstr(WriteInto(&name_, name_size)),
-          &name_size, NULL, &type_, reinterpret_cast<BYTE*>(value_.data()),
-          &value_size_);
+          key_, index_, WriteIntoW(&name_, name_size), &name_size, NULL, &type_,
+          reinterpret_cast<BYTE*>(value_.data()), &value_size_);
     }
 
     if (result == ERROR_SUCCESS) {
@@ -593,12 +585,12 @@
 // RegistryKeyIterator --------------------------------------------------------
 
 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key,
-                                         const char16* folder_key) {
+                                         const wchar_t* folder_key) {
   Initialize(root_key, folder_key, 0);
 }
 
 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key,
-                                         const char16* folder_key,
+                                         const wchar_t* folder_key,
                                          REGSAM wow64access) {
   Initialize(root_key, folder_key, wow64access);
 }
@@ -631,8 +623,8 @@
   if (Valid()) {
     DWORD ncount = static_cast<DWORD>(size(name_));
     FILETIME written;
-    LONG r = ::RegEnumKeyEx(key_, index_, as_writable_wcstr(name_), &ncount,
-                            NULL, NULL, NULL, &written);
+    LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, NULL,
+                            &written);
     if (ERROR_SUCCESS == r)
       return true;
   }
@@ -642,11 +634,11 @@
 }
 
 void RegistryKeyIterator::Initialize(HKEY root_key,
-                                     const char16* folder_key,
+                                     const wchar_t* folder_key,
                                      REGSAM wow64access) {
   DCHECK_EQ(wow64access & ~kWow64AccessMask, static_cast<REGSAM>(0));
-  LONG result = RegOpenKeyEx(root_key, as_wcstr(folder_key), 0,
-                             KEY_READ | wow64access, &key_);
+  LONG result =
+      RegOpenKeyEx(root_key, folder_key, 0, KEY_READ | wow64access, &key_);
   if (result != ERROR_SUCCESS) {
     key_ = NULL;
   } else {
diff --git a/base/win/registry.h b/base/win/registry.h
index 1c57fc9f..f772821 100644
--- a/base/win/registry.h
+++ b/base/win/registry.h
@@ -8,12 +8,12 @@
 #include <stdint.h>
 
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/callback.h"
 #include "base/macros.h"
-#include "base/strings/string16.h"
 #include "base/win/object_watcher.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/windows_types.h"
@@ -37,24 +37,24 @@
 
   RegKey();
   explicit RegKey(HKEY key);
-  RegKey(HKEY rootkey, const char16* subkey, REGSAM access);
+  RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access);
   ~RegKey();
 
-  LONG Create(HKEY rootkey, const char16* subkey, REGSAM access);
+  LONG Create(HKEY rootkey, const wchar_t* subkey, REGSAM access);
 
   LONG CreateWithDisposition(HKEY rootkey,
-                             const char16* subkey,
+                             const wchar_t* subkey,
                              DWORD* disposition,
                              REGSAM access);
 
   // Creates a subkey or open it if it already exists.
-  LONG CreateKey(const char16* name, REGSAM access);
+  LONG CreateKey(const wchar_t* name, REGSAM access);
 
   // Opens an existing reg key.
-  LONG Open(HKEY rootkey, const char16* subkey, REGSAM access);
+  LONG Open(HKEY rootkey, const wchar_t* subkey, REGSAM access);
 
   // Opens an existing reg key, given the relative key name.
-  LONG OpenKey(const char16* relative_key_name, REGSAM access);
+  LONG OpenKey(const wchar_t* relative_key_name, REGSAM access);
 
   // Closes this reg key.
   void Close();
@@ -67,51 +67,51 @@
 
   // Returns false if this key does not have the specified value, or if an error
   // occurrs while attempting to access it.
-  bool HasValue(const char16* value_name) const;
+  bool HasValue(const wchar_t* value_name) const;
 
   // Returns the number of values for this key, or 0 if the number cannot be
   // determined.
   DWORD GetValueCount() const;
 
   // Determines the nth value's name.
-  LONG GetValueNameAt(int index, string16* name) const;
+  LONG GetValueNameAt(int index, std::wstring* name) const;
 
   // True while the key is valid.
   bool Valid() const { return key_ != NULL; }
 
   // Kills a key and everything that lives below it; please be careful when
   // using it.
-  LONG DeleteKey(const char16* name);
+  LONG DeleteKey(const wchar_t* name);
 
   // Deletes an empty subkey.  If the subkey has subkeys or values then this
   // will fail.
-  LONG DeleteEmptyKey(const char16* name);
+  LONG DeleteEmptyKey(const wchar_t* name);
 
   // Deletes a single value within the key.
-  LONG DeleteValue(const char16* name);
+  LONG DeleteValue(const wchar_t* name);
 
   // Getters:
 
   // Reads a REG_DWORD (uint32_t) into |out_value|. If |name| is null or empty,
   // reads the key's default value, if any.
-  LONG ReadValueDW(const char16* name, DWORD* out_value) const;
+  LONG ReadValueDW(const wchar_t* name, DWORD* out_value) const;
 
   // Reads a REG_QWORD (int64_t) into |out_value|. If |name| is null or empty,
   // reads the key's default value, if any.
-  LONG ReadInt64(const char16* name, int64_t* out_value) const;
+  LONG ReadInt64(const wchar_t* name, int64_t* out_value) const;
 
   // Reads a string into |out_value|. If |name| is null or empty, reads
   // the key's default value, if any.
-  LONG ReadValue(const char16* name, string16* out_value) const;
+  LONG ReadValue(const wchar_t* name, std::wstring* out_value) const;
 
   // Reads a REG_MULTI_SZ registry field into a vector of strings. Clears
   // |values| initially and adds further strings to the list. Returns
   // ERROR_CANTREAD if type is not REG_MULTI_SZ.
-  LONG ReadValues(const char16* name, std::vector<string16>* values);
+  LONG ReadValues(const wchar_t* name, std::vector<std::wstring>* values);
 
   // Reads raw data into |data|. If |name| is null or empty, reads the key's
   // default value, if any.
-  LONG ReadValue(const char16* name,
+  LONG ReadValue(const wchar_t* name,
                  void* data,
                  DWORD* dsize,
                  DWORD* dtype) const;
@@ -119,13 +119,13 @@
   // Setters:
 
   // Sets an int32_t value.
-  LONG WriteValue(const char16* name, DWORD in_value);
+  LONG WriteValue(const wchar_t* name, DWORD in_value);
 
   // Sets a string value.
-  LONG WriteValue(const char16* name, const char16* in_value);
+  LONG WriteValue(const wchar_t* name, const wchar_t* in_value);
 
   // Sets raw data, including type.
-  LONG WriteValue(const char16* name,
+  LONG WriteValue(const wchar_t* name,
                   const void* data,
                   DWORD dsize,
                   DWORD dtype);
@@ -143,7 +143,7 @@
   class Watcher;
 
   // Recursively deletes a key and all of its subkeys.
-  static LONG RegDelRecurse(HKEY root_key, const char16* name, REGSAM access);
+  static LONG RegDelRecurse(HKEY root_key, const wchar_t* name, REGSAM access);
 
   HKEY key_;  // The registry key being iterated.
   REGSAM wow64access_;
@@ -156,7 +156,7 @@
 class BASE_EXPORT RegistryValueIterator {
  public:
   // Constructs a Registry Value Iterator with default WOW64 access.
-  RegistryValueIterator(HKEY root_key, const char16* folder_key);
+  RegistryValueIterator(HKEY root_key, const wchar_t* folder_key);
 
   // Constructs a Registry Key Iterator with specific WOW64 access, one of
   // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0.
@@ -164,7 +164,7 @@
   // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE).
   // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx.
   RegistryValueIterator(HKEY root_key,
-                        const char16* folder_key,
+                        const wchar_t* folder_key,
                         REGSAM wow64access);
 
   ~RegistryValueIterator();
@@ -177,8 +177,8 @@
   // Advances to the next registry entry.
   void operator++();
 
-  const char16* Name() const { return name_.c_str(); }
-  const char16* Value() const { return value_.data(); }
+  const wchar_t* Name() const { return name_.c_str(); }
+  const wchar_t* Value() const { return value_.data(); }
   // ValueSize() is in bytes.
   DWORD ValueSize() const { return value_size_; }
   DWORD Type() const { return type_; }
@@ -189,7 +189,7 @@
   // Reads in the current values.
   bool Read();
 
-  void Initialize(HKEY root_key, const char16* folder_key, REGSAM wow64access);
+  void Initialize(HKEY root_key, const wchar_t* folder_key, REGSAM wow64access);
 
   // The registry key being iterated.
   HKEY key_;
@@ -198,8 +198,8 @@
   int index_;
 
   // Current values.
-  string16 name_;
-  std::vector<char16> value_;
+  std::wstring name_;
+  std::vector<wchar_t> value_;
   DWORD value_size_;
   DWORD type_;
 
@@ -209,7 +209,7 @@
 class BASE_EXPORT RegistryKeyIterator {
  public:
   // Constructs a Registry Key Iterator with default WOW64 access.
-  RegistryKeyIterator(HKEY root_key, const char16* folder_key);
+  RegistryKeyIterator(HKEY root_key, const wchar_t* folder_key);
 
   // Constructs a Registry Value Iterator with specific WOW64 access, one of
   // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0.
@@ -217,7 +217,7 @@
   // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE).
   // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx.
   RegistryKeyIterator(HKEY root_key,
-                      const char16* folder_key,
+                      const wchar_t* folder_key,
                       REGSAM wow64access);
 
   ~RegistryKeyIterator();
@@ -230,7 +230,7 @@
   // Advances to the next entry in the folder.
   void operator++();
 
-  const char16* Name() const { return name_; }
+  const wchar_t* Name() const { return name_; }
 
   int Index() const { return index_; }
 
@@ -238,7 +238,7 @@
   // Reads in the current values.
   bool Read();
 
-  void Initialize(HKEY root_key, const char16* folder_key, REGSAM wow64access);
+  void Initialize(HKEY root_key, const wchar_t* folder_key, REGSAM wow64access);
 
   // The registry key being iterated.
   HKEY key_;
@@ -246,7 +246,7 @@
   // Current index of the iteration.
   int index_;
 
-  char16 name_[MAX_PATH];
+  wchar_t name_[MAX_PATH];
 
   DISALLOW_COPY_AND_ASSIGN(RegistryKeyIterator);
 };
diff --git a/base/win/registry_unittest.cc b/base/win/registry_unittest.cc
index 12ebc00..50be1d32 100644
--- a/base/win/registry_unittest.cc
+++ b/base/win/registry_unittest.cc
@@ -23,7 +23,7 @@
 
 namespace {
 
-const char16 kRootKey[] = STRING16_LITERAL("Base_Registry_Unittest");
+const wchar_t kRootKey[] = L"Base_Registry_Unittest";
 
 class RegistryTest : public testing::Test {
  protected:
@@ -38,18 +38,18 @@
   RegistryTest() {}
   void SetUp() override {
     // Create a temporary key.
-    RegKey key(HKEY_CURRENT_USER, STRING16_LITERAL(""), KEY_ALL_ACCESS);
+    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
     key.DeleteKey(kRootKey);
     ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ));
     ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, kRootKey, KEY_READ));
-    foo_software_key_ = STRING16_LITERAL("Software\\");
+    foo_software_key_ = L"Software\\";
     foo_software_key_ += kRootKey;
-    foo_software_key_ += STRING16_LITERAL("\\Foo");
+    foo_software_key_ += L"\\Foo";
   }
 
   void TearDown() override {
     // Clean up the temporary key.
-    RegKey key(HKEY_CURRENT_USER, STRING16_LITERAL(""), KEY_SET_VALUE);
+    RegKey key(HKEY_CURRENT_USER, L"", KEY_SET_VALUE);
     ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey));
     ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ));
   }
@@ -62,7 +62,7 @@
 #endif
   }
 
-  string16 foo_software_key_;
+  std::wstring foo_software_key_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(RegistryTest);
@@ -75,8 +75,8 @@
 TEST_F(RegistryTest, ValueTest) {
   RegKey key;
 
-  string16 foo_key(kRootKey);
-  foo_key += STRING16_LITERAL("\\Foo");
+  std::wstring foo_key(kRootKey);
+  foo_key += L"\\Foo";
   ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
                                       KEY_READ));
 
@@ -85,10 +85,10 @@
                                       KEY_READ | KEY_SET_VALUE));
     ASSERT_TRUE(key.Valid());
 
-    const char16 kStringValueName[] = STRING16_LITERAL("StringValue");
-    const char16 kDWORDValueName[] = STRING16_LITERAL("DWORDValue");
-    const char16 kInt64ValueName[] = STRING16_LITERAL("Int64Value");
-    const char16 kStringData[] = STRING16_LITERAL("string data");
+    const wchar_t kStringValueName[] = L"StringValue";
+    const wchar_t kDWORDValueName[] = L"DWORDValue";
+    const wchar_t kInt64ValueName[] = L"Int64Value";
+    const wchar_t kStringData[] = L"string data";
     const DWORD kDWORDData = 0xdeadbabe;
     const int64_t kInt64Data = 0xdeadbabedeadbabeLL;
 
@@ -103,7 +103,7 @@
     EXPECT_TRUE(key.HasValue(kInt64ValueName));
 
     // Test Read
-    string16 string_value;
+    std::wstring string_value;
     DWORD dword_value = 0;
     int64_t int64_value = 0;
     ASSERT_EQ(ERROR_SUCCESS, key.ReadValue(kStringValueName, &string_value));
@@ -114,7 +114,7 @@
     EXPECT_EQ(kInt64Data, int64_value);
 
     // Make sure out args are not touched if ReadValue fails
-    const char16* kNonExistent = STRING16_LITERAL("NonExistent");
+    const wchar_t* kNonExistent = L"NonExistent";
     ASSERT_NE(ERROR_SUCCESS, key.ReadValue(kNonExistent, &string_value));
     ASSERT_NE(ERROR_SUCCESS, key.ReadValueDW(kNonExistent, &dword_value));
     ASSERT_NE(ERROR_SUCCESS, key.ReadInt64(kNonExistent, &int64_value));
@@ -135,8 +135,8 @@
 
 TEST_F(RegistryTest, BigValueIteratorTest) {
   RegKey key;
-  string16 foo_key(kRootKey);
-  foo_key += STRING16_LITERAL("\\Foo");
+  std::wstring foo_key(kRootKey);
+  foo_key += L"\\Foo";
   ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
                                       KEY_READ));
   ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
@@ -144,7 +144,7 @@
   ASSERT_TRUE(key.Valid());
 
   // Create a test value that is larger than MAX_PATH.
-  string16 data(MAX_PATH * 2, 'a');
+  std::wstring data(MAX_PATH * 2, 'a');
 
   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(data.c_str(), data.c_str()));
 
@@ -153,23 +153,23 @@
   EXPECT_EQ(data, iterator.Name());
   EXPECT_EQ(data, iterator.Value());
   // ValueSize() is in bytes, including NUL.
-  EXPECT_EQ((MAX_PATH * 2 + 1) * sizeof(char16), iterator.ValueSize());
+  EXPECT_EQ((MAX_PATH * 2 + 1) * sizeof(wchar_t), iterator.ValueSize());
   ++iterator;
   EXPECT_FALSE(iterator.Valid());
 }
 
 TEST_F(RegistryTest, TruncatedCharTest) {
   RegKey key;
-  string16 foo_key(kRootKey);
-  foo_key += STRING16_LITERAL("\\Foo");
+  std::wstring foo_key(kRootKey);
+  foo_key += L"\\Foo";
   ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
                                       KEY_READ));
   ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
                                     KEY_READ | KEY_SET_VALUE));
   ASSERT_TRUE(key.Valid());
 
-  const char16 kName[] = STRING16_LITERAL("name");
-  // kData size is not a multiple of sizeof(char16).
+  const wchar_t kName[] = L"name";
+  // kData size is not a multiple of sizeof(wchar_t).
   const uint8_t kData[] = {1, 2, 3, 4, 5};
   EXPECT_EQ(5u, size(kData));
   ASSERT_EQ(ERROR_SUCCESS,
@@ -179,11 +179,11 @@
   ASSERT_TRUE(iterator.Valid());
   // Avoid having to use EXPECT_STREQ here by leveraging StringPiece's
   // operator== to perform a deep comparison.
-  EXPECT_EQ(StringPiece16(kName), StringPiece16(iterator.Name()));
+  EXPECT_EQ(WStringPiece(kName), WStringPiece(iterator.Name()));
   // ValueSize() is in bytes.
   ASSERT_EQ(size(kData), iterator.ValueSize());
   // Value() is NUL terminated.
-  int end = (iterator.ValueSize() + sizeof(char16) - 1) / sizeof(char16);
+  int end = (iterator.ValueSize() + sizeof(wchar_t) - 1) / sizeof(wchar_t);
   EXPECT_NE('\0', iterator.Value()[end - 1]);
   EXPECT_EQ('\0', iterator.Value()[end]);
   EXPECT_EQ(0, std::memcmp(kData, iterator.Value(), size(kData)));
@@ -201,50 +201,47 @@
   //                  \->Moo
   //                  \->Foo
   // and delete kRootKey->Foo
-  string16 foo_key(kRootKey);
-  foo_key += STRING16_LITERAL("\\Foo");
+  std::wstring foo_key(kRootKey);
+  foo_key += L"\\Foo";
   ASSERT_EQ(ERROR_SUCCESS,
             key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(STRING16_LITERAL("Bar"), KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(STRING16_LITERAL("TestValue"),
-                                          STRING16_LITERAL("TestData")));
+  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Bar", KEY_WRITE));
+  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(L"TestValue", L"TestData"));
   ASSERT_EQ(ERROR_SUCCESS,
             key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(STRING16_LITERAL("Moo"), KEY_WRITE));
+  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Moo", KEY_WRITE));
   ASSERT_EQ(ERROR_SUCCESS,
             key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(STRING16_LITERAL("Foo"), KEY_WRITE));
-  foo_key += STRING16_LITERAL("\\Bar");
+  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Foo", KEY_WRITE));
+  foo_key += L"\\Bar";
   ASSERT_EQ(ERROR_SUCCESS,
             key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE));
-  foo_key += STRING16_LITERAL("\\Foo");
-  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(STRING16_LITERAL("Foo"), KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(STRING16_LITERAL("TestValue"),
-                                          STRING16_LITERAL("TestData")));
+  foo_key += L"\\Foo";
+  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Foo", KEY_WRITE));
+  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(L"TestValue", L"TestData"));
   ASSERT_EQ(ERROR_SUCCESS,
             key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));
 
   ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_WRITE));
-  ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(STRING16_LITERAL("Bar")));
-  ASSERT_NE(ERROR_SUCCESS, key.DeleteEmptyKey(STRING16_LITERAL("Foo")));
-  ASSERT_NE(ERROR_SUCCESS,
-            key.DeleteEmptyKey(STRING16_LITERAL("Foo\\Bar\\Foo")));
-  ASSERT_NE(ERROR_SUCCESS, key.DeleteEmptyKey(STRING16_LITERAL("Foo\\Bar")));
-  ASSERT_EQ(ERROR_SUCCESS, key.DeleteEmptyKey(STRING16_LITERAL("Foo\\Foo")));
+  ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(L"Bar"));
+  ASSERT_NE(ERROR_SUCCESS, key.DeleteEmptyKey(L"Foo"));
+  ASSERT_NE(ERROR_SUCCESS, key.DeleteEmptyKey(L"Foo\\Bar\\Foo"));
+  ASSERT_NE(ERROR_SUCCESS, key.DeleteEmptyKey(L"Foo\\Bar"));
+  ASSERT_EQ(ERROR_SUCCESS, key.DeleteEmptyKey(L"Foo\\Foo"));
 
   ASSERT_EQ(ERROR_SUCCESS,
             key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(STRING16_LITERAL("Bar"), KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(STRING16_LITERAL("Foo"), KEY_WRITE));
+  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Bar", KEY_WRITE));
+  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Foo", KEY_WRITE));
   ASSERT_EQ(ERROR_SUCCESS,
             key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(STRING16_LITERAL("")));
+  ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(L""));
   ASSERT_NE(ERROR_SUCCESS,
             key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));
 
   ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(STRING16_LITERAL("Foo")));
-  ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(STRING16_LITERAL("Foo")));
+  ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(L"Foo"));
+  ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(L"Foo"));
   ASSERT_NE(ERROR_SUCCESS,
             key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));
 }
@@ -273,18 +270,15 @@
 
   // Open the non-redirected view of the parent and try to delete the test key.
   ASSERT_EQ(ERROR_SUCCESS,
-            key.Open(HKEY_LOCAL_MACHINE, STRING16_LITERAL("Software"),
-                     KEY_SET_VALUE));
+            key.Open(HKEY_LOCAL_MACHINE, L"Software", KEY_SET_VALUE));
   ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(kRootKey));
-  ASSERT_EQ(ERROR_SUCCESS,
-            key.Open(HKEY_LOCAL_MACHINE, STRING16_LITERAL("Software"),
-                     KEY_SET_VALUE | kNativeViewMask));
+  ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_LOCAL_MACHINE, L"Software",
+                                    KEY_SET_VALUE | kNativeViewMask));
   ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(kRootKey));
 
   // Open the redirected view and delete the key created above.
-  ASSERT_EQ(ERROR_SUCCESS,
-            key.Open(HKEY_LOCAL_MACHINE, STRING16_LITERAL("Software"),
-                     KEY_SET_VALUE | kRedirectedViewMask));
+  ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_LOCAL_MACHINE, L"Software",
+                                    KEY_SET_VALUE | kRedirectedViewMask));
   ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey));
 }
 
@@ -294,13 +288,11 @@
 TEST_F(RegistryTest, SameWowFlags) {
   RegKey key;
 
+  ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_LOCAL_MACHINE, L"Software",
+                                    KEY_READ | KEY_WOW64_64KEY));
   ASSERT_EQ(ERROR_SUCCESS,
-            key.Open(HKEY_LOCAL_MACHINE, STRING16_LITERAL("Software"),
-                     KEY_READ | KEY_WOW64_64KEY));
-  ASSERT_EQ(ERROR_SUCCESS, key.OpenKey(STRING16_LITERAL("Microsoft"),
-                                       KEY_READ | KEY_WOW64_64KEY));
-  ASSERT_EQ(ERROR_SUCCESS, key.OpenKey(STRING16_LITERAL("Windows"),
-                                       KEY_READ | KEY_WOW64_64KEY));
+            key.OpenKey(L"Microsoft", KEY_READ | KEY_WOW64_64KEY));
+  ASSERT_EQ(ERROR_SUCCESS, key.OpenKey(L"Windows", KEY_READ | KEY_WOW64_64KEY));
 }
 
 // TODO(wfh): flaky test on Vista.  See http://crbug.com/377917
@@ -323,14 +315,12 @@
 
   // Open the redirected view of the parent and try to delete the test key
   // from the non-redirected view.
-  ASSERT_EQ(ERROR_SUCCESS,
-            key.Open(HKEY_LOCAL_MACHINE, STRING16_LITERAL("Software"),
-                     KEY_SET_VALUE | kRedirectedViewMask));
+  ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_LOCAL_MACHINE, L"Software",
+                                    KEY_SET_VALUE | kRedirectedViewMask));
   ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(kRootKey));
 
-  ASSERT_EQ(ERROR_SUCCESS,
-            key.Open(HKEY_LOCAL_MACHINE, STRING16_LITERAL("Software"),
-                     KEY_SET_VALUE | kNativeViewMask));
+  ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_LOCAL_MACHINE, L"Software",
+                                    KEY_SET_VALUE | kNativeViewMask));
   ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey));
 }
 
@@ -341,18 +331,18 @@
                      kRootKey,
                      KEY_READ | KEY_CREATE_SUB_KEY));
 
-  ASSERT_NE(ERROR_SUCCESS, key.OpenKey(STRING16_LITERAL("foo"), KEY_READ));
-  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(STRING16_LITERAL("foo"), KEY_READ));
+  ASSERT_NE(ERROR_SUCCESS, key.OpenKey(L"foo", KEY_READ));
+  ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"foo", KEY_READ));
   ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ));
-  ASSERT_EQ(ERROR_SUCCESS, key.OpenKey(STRING16_LITERAL("foo"), KEY_READ));
+  ASSERT_EQ(ERROR_SUCCESS, key.OpenKey(L"foo", KEY_READ));
 
-  string16 foo_key(kRootKey);
-  foo_key += STRING16_LITERAL("\\Foo");
+  std::wstring foo_key(kRootKey);
+  foo_key += L"\\Foo";
   ASSERT_EQ(ERROR_SUCCESS,
             key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));
 
   ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_WRITE));
-  ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(STRING16_LITERAL("foo")));
+  ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(L"foo"));
 }
 
 class TestChangeDelegate {
@@ -380,8 +370,8 @@
   TestChangeDelegate delegate;
   test::TaskEnvironment task_environment;
 
-  string16 foo_key(kRootKey);
-  foo_key += STRING16_LITERAL("\\Foo");
+  std::wstring foo_key(kRootKey);
+  foo_key += L"\\Foo";
   ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
                                       KEY_READ));
 
@@ -394,8 +384,7 @@
   ASSERT_EQ(ERROR_SUCCESS, key2.Open(HKEY_CURRENT_USER, foo_key.c_str(),
                                       KEY_READ | KEY_SET_VALUE));
   ASSERT_TRUE(key2.Valid());
-  EXPECT_EQ(ERROR_SUCCESS, key2.WriteValue(STRING16_LITERAL("name"),
-                                           STRING16_LITERAL("data")));
+  EXPECT_EQ(ERROR_SUCCESS, key2.WriteValue(L"name", L"data"));
 
   // Allow delivery of the notification.
   EXPECT_FALSE(delegate.WasCalled());
@@ -408,8 +397,7 @@
       BindRepeating(&TestChangeDelegate::OnKeyChanged, Unretained(&delegate))));
 
   // Change something else.
-  EXPECT_EQ(ERROR_SUCCESS, key2.WriteValue(STRING16_LITERAL("name2"),
-                                           STRING16_LITERAL("data2")));
+  EXPECT_EQ(ERROR_SUCCESS, key2.WriteValue(L"name2", L"data2"));
   RunLoop().Run();
   ASSERT_TRUE(delegate.WasCalled());
 
diff --git a/base/win/scoped_bstr.cc b/base/win/scoped_bstr.cc
index dc68cbac..94d7d08 100644
--- a/base/win/scoped_bstr.cc
+++ b/base/win/scoped_bstr.cc
@@ -16,8 +16,8 @@
 
 namespace {
 
-BSTR AllocBstrOrDie(StringPiece16 non_bstr) {
-  BSTR result = ::SysAllocStringLen(as_wcstr(non_bstr),
+BSTR AllocBstrOrDie(WStringPiece non_bstr) {
+  BSTR result = ::SysAllocStringLen(non_bstr.data(),
                                     checked_cast<UINT>(non_bstr.length()));
   if (!result) {
     base::TerminateBecauseOutOfMemory((non_bstr.length() + 1) *
@@ -35,7 +35,7 @@
 
 }  // namespace
 
-ScopedBstr::ScopedBstr(StringPiece16 non_bstr)
+ScopedBstr::ScopedBstr(WStringPiece non_bstr)
     : bstr_(AllocBstrOrDie(non_bstr)) {}
 
 ScopedBstr::~ScopedBstr() {
@@ -68,7 +68,7 @@
   return &bstr_;
 }
 
-BSTR ScopedBstr::Allocate(StringPiece16 str) {
+BSTR ScopedBstr::Allocate(WStringPiece str) {
   Reset(AllocBstrOrDie(str));
   return bstr_;
 }
diff --git a/base/win/scoped_bstr.h b/base/win/scoped_bstr.h
index 658e815..a3d3684 100644
--- a/base/win/scoped_bstr.h
+++ b/base/win/scoped_bstr.h
@@ -12,7 +12,6 @@
 #include "base/base_export.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 
 namespace base {
@@ -28,7 +27,7 @@
   //
   // NOTE: Do not pass a BSTR to this constructor expecting ownership to
   // be transferred - even though it compiles! ;-)
-  explicit ScopedBstr(StringPiece16 non_bstr);
+  explicit ScopedBstr(WStringPiece non_bstr);
   ~ScopedBstr();
 
   // Give ScopedBstr ownership over an already allocated BSTR or null.
@@ -44,7 +43,7 @@
   // ScopedBstr instance, call |reset| instead.
   //
   // Returns a pointer to the new BSTR.
-  BSTR Allocate(StringPiece16 str);
+  BSTR Allocate(WStringPiece str);
 
   // Allocates a new BSTR with the specified number of bytes.
   // Returns a pointer to the new BSTR.
diff --git a/base/win/scoped_bstr_unittest.cc b/base/win/scoped_bstr_unittest.cc
index 1be543e1..66cb0bd 100644
--- a/base/win/scoped_bstr_unittest.cc
+++ b/base/win/scoped_bstr_unittest.cc
@@ -7,8 +7,6 @@
 #include <stddef.h>
 
 #include "base/stl_util.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
@@ -16,8 +14,8 @@
 
 namespace {
 
-static const char16 kTestString1[] = STRING16_LITERAL("123");
-static const char16 kTestString2[] = STRING16_LITERAL("456789");
+static const wchar_t kTestString1[] = L"123";
+static const wchar_t kTestString2[] = L"456789";
 size_t test1_len = size(kTestString1) - 1;
 size_t test2_len = size(kTestString2) - 1;
 
@@ -35,7 +33,7 @@
 }
 
 void GiveMeABstr(BSTR* ret) {
-  *ret = SysAllocString(as_wcstr(kTestString1));
+  *ret = SysAllocString(kTestString1);
 }
 
 void BasicBstrTests() {
@@ -47,10 +45,10 @@
   b1.Swap(b2);
   EXPECT_EQ(test1_len, b2.Length());
   EXPECT_EQ(0u, b1.Length());
-  EXPECT_STREQ(b2, as_wcstr(kTestString1));
+  EXPECT_STREQ(b2, kTestString1);
   BSTR tmp = b2.Release();
   EXPECT_TRUE(tmp != NULL);
-  EXPECT_STREQ(tmp, as_wcstr(kTestString1));
+  EXPECT_STREQ(tmp, kTestString1);
   EXPECT_TRUE(b2 == NULL);
   SysFreeString(tmp);
 
@@ -60,7 +58,7 @@
   EXPECT_TRUE(b2.AllocateBytes(100) != NULL);
   EXPECT_EQ(100u, b2.ByteLength());
   EXPECT_EQ(100 / sizeof(kTestString1[0]), b2.Length());
-  lstrcpy(static_cast<BSTR>(b2), as_wcstr(kTestString1));
+  lstrcpy(static_cast<BSTR>(b2), kTestString1);
   EXPECT_EQ(test1_len, static_cast<size_t>(lstrlen(b2)));
   EXPECT_EQ(100 / sizeof(kTestString1[0]), b2.Length());
   b2.SetByteLen(lstrlen(b2) * sizeof(kTestString2[0]));
diff --git a/base/win/shortcut.cc b/base/win/shortcut.cc
index 289f5e6..5d9f1027 100644
--- a/base/win/shortcut.cc
+++ b/base/win/shortcut.cc
@@ -115,7 +115,7 @@
   }
 
   if (properties.options & ShortcutProperties::PROPERTIES_ARGUMENTS) {
-    if (FAILED(i_shell_link->SetArguments(as_wcstr(properties.arguments))))
+    if (FAILED(i_shell_link->SetArguments(properties.arguments.c_str())))
       return false;
   } else if (old_i_persist_file.Get()) {
     wchar_t current_arguments[MAX_PATH] = {0};
@@ -126,7 +126,7 @@
   }
 
   if ((properties.options & ShortcutProperties::PROPERTIES_DESCRIPTION) &&
-      FAILED(i_shell_link->SetDescription(as_wcstr(properties.description)))) {
+      FAILED(i_shell_link->SetDescription(properties.description.c_str()))) {
     return false;
   }
 
@@ -225,42 +225,39 @@
   // Reset |properties|.
   properties->options = 0;
 
-  char16 temp[MAX_PATH];
+  wchar_t temp[MAX_PATH];
   if (options & ShortcutProperties::PROPERTIES_TARGET) {
-    if (FAILED(i_shell_link->GetPath(as_writable_wcstr(temp), MAX_PATH, NULL,
-                                     SLGP_UNCPRIORITY))) {
+    if (FAILED(i_shell_link->GetPath(temp, MAX_PATH, NULL, SLGP_UNCPRIORITY))) {
       return false;
     }
-    properties->set_target(FilePath(temp));
+    properties->set_target(FilePath(AsStringPiece16(temp)));
   }
 
   if (options & ShortcutProperties::PROPERTIES_WORKING_DIR) {
-    if (FAILED(i_shell_link->GetWorkingDirectory(as_writable_wcstr(temp),
-                                                 MAX_PATH)))
+    if (FAILED(i_shell_link->GetWorkingDirectory(temp, MAX_PATH)))
       return false;
-    properties->set_working_dir(FilePath(temp));
+    properties->set_working_dir(FilePath(AsStringPiece16(temp)));
   }
 
   if (options & ShortcutProperties::PROPERTIES_ARGUMENTS) {
-    if (FAILED(i_shell_link->GetArguments(as_writable_wcstr(temp), MAX_PATH)))
+    if (FAILED(i_shell_link->GetArguments(temp, MAX_PATH)))
       return false;
     properties->set_arguments(temp);
   }
 
   if (options & ShortcutProperties::PROPERTIES_DESCRIPTION) {
     // Note: description length constrained by MAX_PATH.
-    if (FAILED(i_shell_link->GetDescription(as_writable_wcstr(temp), MAX_PATH)))
+    if (FAILED(i_shell_link->GetDescription(temp, MAX_PATH)))
       return false;
     properties->set_description(temp);
   }
 
   if (options & ShortcutProperties::PROPERTIES_ICON) {
     int temp_index;
-    if (FAILED(i_shell_link->GetIconLocation(as_writable_wcstr(temp), MAX_PATH,
-                                             &temp_index))) {
+    if (FAILED(i_shell_link->GetIconLocation(temp, MAX_PATH, &temp_index))) {
       return false;
     }
-    properties->set_icon(FilePath(temp), temp_index);
+    properties->set_icon(FilePath(AsStringPiece16(temp)), temp_index);
   }
 
   if (options & (ShortcutProperties::PROPERTIES_APP_ID |
@@ -278,10 +275,10 @@
       }
       switch (pv_app_id.get().vt) {
         case VT_EMPTY:
-          properties->set_app_id(string16());
+          properties->set_app_id(std::wstring());
           break;
         case VT_LPWSTR:
-          properties->set_app_id(WideToUTF16(pv_app_id.get().pwszVal));
+          properties->set_app_id(pv_app_id.get().pwszVal);
           break;
         default:
           NOTREACHED() << "Unexpected variant type: " << pv_app_id.get().vt;
@@ -336,7 +333,7 @@
 
 bool ResolveShortcut(const FilePath& shortcut_path,
                      FilePath* target_path,
-                     string16* args) {
+                     std::wstring* args) {
   uint32_t options = 0;
   if (target_path)
     options |= ShortcutProperties::PROPERTIES_TARGET;
diff --git a/base/win/shortcut.h b/base/win/shortcut.h
index 38c12b7..9f656ad5 100644
--- a/base/win/shortcut.h
+++ b/base/win/shortcut.h
@@ -11,7 +11,6 @@
 #include "base/base_export.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
-#include "base/strings/string16.h"
 
 namespace base {
 namespace win {
@@ -62,14 +61,14 @@
     options |= PROPERTIES_WORKING_DIR;
   }
 
-  void set_arguments(const string16& arguments_in) {
+  void set_arguments(const std::wstring& arguments_in) {
     // Size restriction as per MSDN at http://goo.gl/TJ7q5.
     DCHECK(arguments_in.size() < MAX_PATH);
     arguments = arguments_in;
     options |= PROPERTIES_ARGUMENTS;
   }
 
-  void set_description(const string16& description_in) {
+  void set_description(const std::wstring& description_in) {
     // Size restriction as per MSDN at http://goo.gl/OdNQq.
     DCHECK(description_in.size() < MAX_PATH);
     description = description_in;
@@ -82,7 +81,7 @@
     options |= PROPERTIES_ICON;
   }
 
-  void set_app_id(const string16& app_id_in) {
+  void set_app_id(const std::wstring& app_id_in) {
     app_id = app_id_in;
     options |= PROPERTIES_APP_ID;
   }
@@ -104,16 +103,16 @@
   FilePath working_dir;
   // The arguments to be applied to |target| when launching from this shortcut.
   // The length of this string must be less than MAX_PATH.
-  string16 arguments;
+  std::wstring arguments;
   // The localized description of the shortcut.
   // The length of this string must be less than MAX_PATH.
-  string16 description;
+  std::wstring description;
   // The path to the icon (can be a dll or exe, in which case |icon_index| is
   // the resource id).
   FilePath icon;
   int icon_index;
   // The app model id for the shortcut.
-  string16 app_id;
+  std::wstring app_id;
   // Whether this is a dual mode shortcut (Win8+).
   bool dual_mode;
   // The CLSID of the COM object registered with the OS via the shortcut. This
@@ -159,7 +158,7 @@
 // |shortcut_path| and |target_path|.
 BASE_EXPORT bool ResolveShortcut(const FilePath& shortcut_path,
                                  FilePath* target_path,
-                                 string16* args);
+                                 std::wstring* args);
 
 // Pin to taskbar is only supported on Windows 7 and Windows 8. Returns true on
 // those platforms.
diff --git a/base/win/shortcut_unittest.cc b/base/win/shortcut_unittest.cc
index 992c1b1..76c80dcf 100644
--- a/base/win/shortcut_unittest.cc
+++ b/base/win/shortcut_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/stl_util.h"
-#include "base/strings/string16.h"
 #include "base/test/test_file_util.h"
 #include "base/test/test_shortcut_win.h"
 #include "base/win/scoped_com_initializer.h"
@@ -42,10 +41,10 @@
 
       link_properties_.set_target(target_file);
       link_properties_.set_working_dir(temp_dir_.GetPath());
-      link_properties_.set_arguments(STRING16_LITERAL("--magic --awesome"));
-      link_properties_.set_description(STRING16_LITERAL("Chrome is awesome."));
+      link_properties_.set_arguments(L"--magic --awesome");
+      link_properties_.set_description(L"Chrome is awesome.");
       link_properties_.set_icon(link_properties_.target, 4);
-      link_properties_.set_app_id(STRING16_LITERAL("Chrome"));
+      link_properties_.set_app_id(L"Chrome");
       link_properties_.set_dual_mode(false);
 
       // The CLSID below was randomly selected.
@@ -68,12 +67,10 @@
 
       link_properties_2_.set_target(target_file_2);
       link_properties_2_.set_working_dir(temp_dir_2_.GetPath());
-      link_properties_2_.set_arguments(STRING16_LITERAL("--super --crazy"));
-      link_properties_2_.set_description(
-          STRING16_LITERAL("The best in the west."));
+      link_properties_2_.set_arguments(L"--super --crazy");
+      link_properties_2_.set_description(L"The best in the west.");
       link_properties_2_.set_icon(icon_path_2, 0);
-      link_properties_2_.set_app_id(
-          STRING16_LITERAL("Chrome.UserLevelCrazySuffix"));
+      link_properties_2_.set_app_id(L"Chrome.UserLevelCrazySuffix");
       link_properties_2_.set_dual_mode(true);
       link_properties_2_.set_toast_activator_clsid(CLSID_NULL);
     }
@@ -133,11 +130,11 @@
   ValidatePathsAreEqual(only_target_properties.target,
                         properties_read_2.target);
   ValidatePathsAreEqual(FilePath(), properties_read_2.working_dir);
-  EXPECT_EQ(STRING16_LITERAL(""), properties_read_2.arguments);
-  EXPECT_EQ(STRING16_LITERAL(""), properties_read_2.description);
+  EXPECT_EQ(L"", properties_read_2.arguments);
+  EXPECT_EQ(L"", properties_read_2.description);
   ValidatePathsAreEqual(FilePath(), properties_read_2.icon);
   EXPECT_EQ(0, properties_read_2.icon_index);
-  EXPECT_EQ(STRING16_LITERAL(""), properties_read_2.app_id);
+  EXPECT_EQ(L"", properties_read_2.app_id);
   EXPECT_FALSE(properties_read_2.dual_mode);
   EXPECT_EQ(CLSID_NULL, properties_read_2.toast_activator_clsid);
 }
@@ -162,7 +159,7 @@
       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
 
   FilePath resolved_name;
-  string16 args;
+  std::wstring args;
   EXPECT_TRUE(ResolveShortcut(link_file_, &resolved_name, &args));
 
   char read_contents[base::size(kFileContents)];
@@ -260,14 +257,14 @@
       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
 
   ShortcutProperties clear_arguments_properties;
-  clear_arguments_properties.set_arguments(string16());
+  clear_arguments_properties.set_arguments(std::wstring());
 
   ASSERT_TRUE(CreateOrUpdateShortcutLink(
       link_file_, clear_arguments_properties,
       SHORTCUT_UPDATE_EXISTING));
 
   ShortcutProperties expected_properties = link_properties_;
-  expected_properties.set_arguments(string16());
+  expected_properties.set_arguments(std::wstring());
   ValidateShortcut(link_file_, expected_properties);
 }
 
@@ -303,7 +300,7 @@
   ShortcutProperties expected_properties(new_properties);
   expected_properties.set_working_dir(FilePath());
   expected_properties.set_icon(FilePath(), 0);
-  expected_properties.set_app_id(string16());
+  expected_properties.set_app_id(std::wstring());
   expected_properties.set_dual_mode(false);
   ValidateShortcut(link_file_, expected_properties);
 }
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index 7c87ace4..97301a1 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -40,6 +40,7 @@
 #include "base/macros.h"
 #include "base/scoped_native_library.h"
 #include "base/strings/string_util.h"
+#include "base/strings/string_util_win.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/scoped_thread_priority.h"
@@ -334,20 +335,20 @@
       break;
 
     // Get the device ID.
-    char16 device_id[MAX_DEVICE_ID_LEN];
-    CONFIGRET status =
-        CM_Get_Device_ID(device_info_data.DevInst, as_writable_wcstr(device_id),
-                         MAX_DEVICE_ID_LEN, 0);
+    wchar_t device_id[MAX_DEVICE_ID_LEN];
+    CONFIGRET status = CM_Get_Device_ID(device_info_data.DevInst, device_id,
+                                        MAX_DEVICE_ID_LEN, 0);
     if (status == CR_SUCCESS) {
       // To reduce the scope of the hack we only look for ACPI and HID\\VID
       // prefixes in the keyboard device ids.
-      if (StartsWith(device_id, STRING16_LITERAL("ACPI"),
+      if (StartsWith(base::AsStringPiece16(device_id), STRING16_LITERAL("ACPI"),
                      CompareCase::INSENSITIVE_ASCII) ||
-          StartsWith(device_id, STRING16_LITERAL("HID\\VID"),
+          StartsWith(base::AsStringPiece16(device_id),
+                     STRING16_LITERAL("HID\\VID"),
                      CompareCase::INSENSITIVE_ASCII)) {
         if (reason) {
           *reason += "device: ";
-          *reason += UTF16ToUTF8(device_id);
+          *reason += WideToUTF8(device_id);
           *reason += '\n';
         }
         // The heuristic we are using is to check the count of keyboards and
@@ -374,7 +375,7 @@
   DCHECK(success);
 }
 
-bool GetUserSidString(string16* user_sid) {
+bool GetUserSidString(std::wstring* user_sid) {
   // Get the current token.
   HANDLE token = NULL;
   if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
@@ -396,7 +397,7 @@
   if (!::ConvertSidToStringSid(user->User.Sid, &sid_string))
     return false;
 
-  *user_sid = as_u16cstr(sid_string);
+  *user_sid = sid_string;
 
   ::LocalFree(sid_string);
 
@@ -409,14 +410,11 @@
   //   http://code.google.com/p/chromium/issues/detail?id=61644
   ThreadRestrictions::ScopedAllowIO allow_io;
 
-  RegKey key(
-      HKEY_LOCAL_MACHINE,
-      STRING16_LITERAL(
-          "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"),
-      KEY_READ);
+  RegKey key(HKEY_LOCAL_MACHINE,
+             L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
+             KEY_READ);
   DWORD uac_enabled;
-  if (key.ReadValueDW(STRING16_LITERAL("EnableLUA"), &uac_enabled) !=
-      ERROR_SUCCESS) {
+  if (key.ReadValueDW(L"EnableLUA", &uac_enabled) != ERROR_SUCCESS) {
     return true;
   }
   // Users can set the EnableLUA value to something arbitrary, like 2, which
@@ -440,9 +438,9 @@
 
 bool SetStringValueForPropertyStore(IPropertyStore* property_store,
                                     const PROPERTYKEY& property_key,
-                                    const char16* property_string_value) {
+                                    const wchar_t* property_string_value) {
   ScopedPropVariant property_value;
-  if (FAILED(InitPropVariantFromString(as_wcstr(property_string_value),
+  if (FAILED(InitPropVariantFromString(property_string_value,
                                        property_value.Receive()))) {
     return false;
   }
@@ -466,36 +464,37 @@
 }
 
 bool SetAppIdForPropertyStore(IPropertyStore* property_store,
-                              const char16* app_id) {
+                              const wchar_t* app_id) {
   // App id should be less than 64 chars and contain no space. And recommended
   // format is CompanyName.ProductName[.SubProduct.ProductNumber].
   // See http://msdn.microsoft.com/en-us/library/dd378459%28VS.85%29.aspx
-  DCHECK_LT(lstrlen(as_wcstr(app_id)), 64);
-  DCHECK_EQ(wcschr(as_wcstr(app_id), L' '), nullptr);
+  DCHECK_LT(lstrlen(app_id), 64);
+  DCHECK_EQ(wcschr(app_id, L' '), nullptr);
 
   return SetStringValueForPropertyStore(property_store,
                                         PKEY_AppUserModel_ID,
                                         app_id);
 }
 
-static const char16 kAutoRunKeyPath[] =
-    STRING16_LITERAL("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
+static const wchar_t kAutoRunKeyPath[] =
+    L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
 
-bool AddCommandToAutoRun(HKEY root_key, const string16& name,
-                         const string16& command) {
+bool AddCommandToAutoRun(HKEY root_key,
+                         const std::wstring& name,
+                         const std::wstring& command) {
   RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE);
   return (autorun_key.WriteValue(name.c_str(), command.c_str()) ==
       ERROR_SUCCESS);
 }
 
-bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name) {
+bool RemoveCommandFromAutoRun(HKEY root_key, const std::wstring& name) {
   RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE);
   return (autorun_key.DeleteValue(name.c_str()) == ERROR_SUCCESS);
 }
 
 bool ReadCommandFromAutoRun(HKEY root_key,
-                            const string16& name,
-                            string16* command) {
+                            const std::wstring& name,
+                            std::wstring* command) {
   RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_QUERY_VALUE);
   return (autorun_key.ReadValue(name.c_str(), command) == ERROR_SUCCESS);
 }
@@ -766,9 +765,9 @@
   return nullptr;
 }
 
-string16 GetWindowObjectName(HANDLE handle) {
+std::wstring GetWindowObjectName(HANDLE handle) {
   // Get the size of the name.
-  string16 object_name;
+  std::wstring object_name;
 
   DWORD size = 0;
   ::GetUserObjectInformation(handle, UOI_NAME, nullptr, 0, &size);
@@ -781,7 +780,7 @@
 
   // Query the name of the object.
   if (!::GetUserObjectInformation(
-          handle, UOI_NAME, WriteInto(&object_name, size / sizeof(wchar_t)),
+          handle, UOI_NAME, WriteIntoW(&object_name, size / sizeof(wchar_t)),
           size, &size)) {
     DPCHECK(false);
   }
@@ -789,13 +788,14 @@
   return object_name;
 }
 
-bool IsRunningUnderDesktopName(StringPiece16 desktop_name) {
+bool IsRunningUnderDesktopName(WStringPiece desktop_name) {
   HDESK thread_desktop = ::GetThreadDesktop(::GetCurrentThreadId());
   if (!thread_desktop)
     return false;
 
-  string16 current_desktop_name = GetWindowObjectName(thread_desktop);
-  return EqualsCaseInsensitiveASCII(current_desktop_name, desktop_name);
+  std::wstring current_desktop_name = GetWindowObjectName(thread_desktop);
+  return EqualsCaseInsensitiveASCII(AsStringPiece16(current_desktop_name),
+                                    AsStringPiece16(desktop_name));
 }
 
 // This method is used to detect whether current session is a remote session.
@@ -810,14 +810,13 @@
   if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &current_session_id))
     return false;
 
-  static constexpr char16 kRdpSettingsKeyName[] =
-      STRING16_LITERAL("SYSTEM\\CurrentControlSet\\Control\\Terminal Server");
+  static constexpr wchar_t kRdpSettingsKeyName[] =
+      L"SYSTEM\\CurrentControlSet\\Control\\Terminal Server";
   RegKey key(HKEY_LOCAL_MACHINE, kRdpSettingsKeyName, KEY_READ);
   if (!key.Valid())
     return false;
 
-  static constexpr char16 kGlassSessionIdValueName[] =
-      STRING16_LITERAL("GlassSessionId");
+  static constexpr wchar_t kGlassSessionIdValueName[] = L"GlassSessionId";
   DWORD glass_session_id = 0;
   if (key.ReadValueDW(kGlassSessionIdValueName, &glass_session_id) !=
       ERROR_SUCCESS)
diff --git a/base/win/win_util.h b/base/win/win_util.h
index 921b5c1..8c938957 100644
--- a/base/win/win_util.h
+++ b/base/win/win_util.h
@@ -58,7 +58,7 @@
 
 // Returns the string representing the current user sid. Does not modify
 // |user_sid| on failure.
-BASE_EXPORT bool GetUserSidString(string16* user_sid);
+BASE_EXPORT bool GetUserSidString(std::wstring* user_sid);
 
 // Returns false if user account control (UAC) has been disabled with the
 // EnableLUA registry flag. Returns true if user account control is enabled.
@@ -78,7 +78,7 @@
 BASE_EXPORT bool SetStringValueForPropertyStore(
     IPropertyStore* property_store,
     const PROPERTYKEY& property_key,
-    const char16* property_string_value);
+    const wchar_t* property_string_value);
 
 // Sets the CLSID value for a given key in a given IPropertyStore.
 BASE_EXPORT bool SetClsidForPropertyStore(IPropertyStore* property_store,
@@ -89,22 +89,23 @@
 // for tagging application/chromium shortcut, browser window and jump list for
 // Win7.
 BASE_EXPORT bool SetAppIdForPropertyStore(IPropertyStore* property_store,
-                                          const char16* app_id);
+                                          const wchar_t* app_id);
 
 // Adds the specified |command| using the specified |name| to the AutoRun key.
 // |root_key| could be HKCU or HKLM or the root of any user hive.
 BASE_EXPORT bool AddCommandToAutoRun(HKEY root_key,
-                                     const string16& name,
-                                     const string16& command);
+                                     const std::wstring& name,
+                                     const std::wstring& command);
 // Removes the command specified by |name| from the AutoRun key. |root_key|
 // could be HKCU or HKLM or the root of any user hive.
-BASE_EXPORT bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name);
+BASE_EXPORT bool RemoveCommandFromAutoRun(HKEY root_key,
+                                          const std::wstring& name);
 
 // Reads the command specified by |name| from the AutoRun key. |root_key|
 // could be HKCU or HKLM or the root of any user hive. Used for unit-tests.
 BASE_EXPORT bool ReadCommandFromAutoRun(HKEY root_key,
-                                        const string16& name,
-                                        string16* command);
+                                        const std::wstring& name,
+                                        std::wstring* command);
 
 // Sets whether to crash the process during exit. This is inspected by DLLMain
 // and used to intercept unexpected terminations of the process (via calls to
@@ -216,12 +217,12 @@
     NativeLibraryLoadError* error = nullptr);
 
 // Returns the name of a desktop or a window station.
-BASE_EXPORT string16 GetWindowObjectName(HANDLE handle);
+BASE_EXPORT std::wstring GetWindowObjectName(HANDLE handle);
 
 // Checks if the calling thread is running under a desktop with the name
 // given by |desktop_name|. |desktop_name| is ASCII case insensitive (non-ASCII
 // characters will be compared with exact matches).
-BASE_EXPORT bool IsRunningUnderDesktopName(StringPiece16 desktop_name);
+BASE_EXPORT bool IsRunningUnderDesktopName(WStringPiece desktop_name);
 
 // Returns true if current session is a remote session.
 BASE_EXPORT bool IsCurrentSessionRemote();
diff --git a/base/win/win_util_unittest.cc b/base/win/win_util_unittest.cc
index 1b161aa..c0c7b239 100644
--- a/base/win/win_util_unittest.cc
+++ b/base/win/win_util_unittest.cc
@@ -43,7 +43,7 @@
 }
 
 TEST(BaseWinUtilTest, TestGetUserSidString) {
-  string16 user_sid;
+  std::wstring user_sid;
   EXPECT_TRUE(GetUserSidString(&user_sid));
   EXPECT_TRUE(!user_sid.empty());
 }
@@ -101,9 +101,9 @@
 }
 
 TEST(BaseWinUtilTest, GetWindowObjectName) {
-  base::string16 created_desktop_name(STRING16_LITERAL("test_desktop"));
+  std::wstring created_desktop_name(L"test_desktop");
   HDESK desktop_handle =
-      ::CreateDesktop(as_wcstr(created_desktop_name), nullptr, nullptr, 0,
+      ::CreateDesktop(created_desktop_name.c_str(), nullptr, nullptr, 0,
                       DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS |
                           READ_CONTROL | WRITE_DAC | WRITE_OWNER,
                       nullptr);
@@ -117,13 +117,15 @@
   HDESK thread_desktop = ::GetThreadDesktop(::GetCurrentThreadId());
 
   ASSERT_NE(thread_desktop, nullptr);
-  base::string16 desktop_name = GetWindowObjectName(thread_desktop);
+  std::wstring desktop_name = GetWindowObjectName(thread_desktop);
 
   EXPECT_TRUE(IsRunningUnderDesktopName(desktop_name));
-  EXPECT_TRUE(IsRunningUnderDesktopName(base::ToLowerASCII(desktop_name)));
-  EXPECT_TRUE(IsRunningUnderDesktopName(base::ToUpperASCII(desktop_name)));
-  EXPECT_FALSE(IsRunningUnderDesktopName(
-      desktop_name + STRING16_LITERAL("_non_existent_desktop_name")));
+  EXPECT_TRUE(IsRunningUnderDesktopName(
+      AsWString(ToLowerASCII(AsStringPiece16(desktop_name)))));
+  EXPECT_TRUE(IsRunningUnderDesktopName(
+      AsWString(ToUpperASCII(AsStringPiece16(desktop_name)))));
+  EXPECT_FALSE(
+      IsRunningUnderDesktopName(desktop_name + L"_non_existent_desktop_name"));
 }
 
 }  // namespace win
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc
index 1d3721944..88974fa 100644
--- a/base/win/windows_version.cc
+++ b/base/win/windows_version.cc
@@ -14,7 +14,6 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
-#include "base/strings/string16.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/registry.h"
@@ -34,8 +33,8 @@
 
 // The values under the CurrentVersion registry hive are mirrored under
 // the corresponding Wow6432 hive.
-constexpr char16 kRegKeyWindowsNTCurrentVersion[] =
-    STRING16_LITERAL("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
+constexpr wchar_t kRegKeyWindowsNTCurrentVersion[] =
+    L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
 
 // Returns the "UBR" (Windows 10 patch number) and "ReleaseId" (Windows 10
 // release number) from the registry. "UBR" is an undocumented value and will be
@@ -43,16 +42,16 @@
 // value is not found.
 std::pair<int, std::string> GetVersionData() {
   DWORD ubr = 0;
-  string16 release_id;
+  std::wstring release_id;
   RegKey key;
 
   if (key.Open(HKEY_LOCAL_MACHINE, kRegKeyWindowsNTCurrentVersion,
                KEY_QUERY_VALUE) == ERROR_SUCCESS) {
-    key.ReadValueDW(STRING16_LITERAL("UBR"), &ubr);
-    key.ReadValue(STRING16_LITERAL("ReleaseId"), &release_id);
+    key.ReadValueDW(L"UBR", &ubr);
+    key.ReadValue(L"ReleaseId", &release_id);
   }
 
-  return std::make_pair(static_cast<int>(ubr), UTF16ToUTF8(release_id));
+  return std::make_pair(static_cast<int>(ubr), WideToUTF8(release_id));
 }
 
 const _SYSTEM_INFO& GetSystemInfoStorage() {
@@ -230,12 +229,12 @@
 
 std::string OSInfo::processor_model_name() {
   if (processor_model_name_.empty()) {
-    const char16 kProcessorNameString[] =
-        STRING16_LITERAL("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
+    const wchar_t kProcessorNameString[] =
+        L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
     RegKey key(HKEY_LOCAL_MACHINE, kProcessorNameString, KEY_READ);
-    string16 value;
-    key.ReadValue(STRING16_LITERAL("ProcessorNameString"), &value);
-    processor_model_name_ = UTF16ToUTF8(value);
+    std::wstring value;
+    key.ReadValue(L"ProcessorNameString", &value);
+    processor_model_name_ = WideToUTF8(value);
   }
   return processor_model_name_;
 }
diff --git a/base/win/wmi.cc b/base/win/wmi.cc
index 4d5e094c..c7da8a3 100644
--- a/base/win/wmi.cc
+++ b/base/win/wmi.cc
@@ -36,9 +36,9 @@
     return false;
 
   ComPtr<IWbemServices> wmi_services_r;
-  hr = wmi_locator->ConnectServer(ScopedBstr(STRING16_LITERAL("ROOT\\CIMV2")),
-                                  nullptr, nullptr, nullptr, 0, nullptr,
-                                  nullptr, &wmi_services_r);
+  hr =
+      wmi_locator->ConnectServer(ScopedBstr(L"ROOT\\CIMV2"), nullptr, nullptr,
+                                 nullptr, 0, nullptr, nullptr, &wmi_services_r);
   if (FAILED(hr))
     return false;
 
@@ -55,8 +55,8 @@
 }
 
 bool CreateWmiClassMethodObject(IWbemServices* wmi_services,
-                                StringPiece16 class_name,
-                                StringPiece16 method_name,
+                                WStringPiece class_name,
+                                WStringPiece method_name,
                                 ComPtr<IWbemClassObject>* class_instance) {
   // We attempt to instantiate a COM object that represents a WMI object plus
   // a method rolled into one entity.
@@ -90,20 +90,20 @@
 // NOTE: The documentation for the Create method suggests that the ProcessId
 // parameter and return value are of type uint32_t, but when we call the method
 // the values in the returned out_params, are VT_I4, which is int32_t.
-bool WmiLaunchProcess(const string16& command_line, int* process_id) {
+bool WmiLaunchProcess(const std::wstring& command_line, int* process_id) {
   ComPtr<IWbemServices> wmi_local;
   if (!CreateLocalWmiConnection(true, &wmi_local))
     return false;
 
-  static constexpr char16 class_name[] = STRING16_LITERAL("Win32_Process");
-  static constexpr char16 method_name[] = STRING16_LITERAL("Create");
+  static constexpr wchar_t class_name[] = L"Win32_Process";
+  static constexpr wchar_t method_name[] = L"Create";
   ComPtr<IWbemClassObject> process_create;
   if (!CreateWmiClassMethodObject(wmi_local.Get(), class_name, method_name,
                                   &process_create)) {
     return false;
   }
 
-  ScopedVariant b_command_line(as_wcstr(command_line));
+  ScopedVariant b_command_line(command_line.c_str());
 
   if (FAILED(process_create->Put(L"CommandLine", 0, b_command_line.AsInput(),
                                  0))) {
@@ -151,14 +151,14 @@
 
 void WmiComputerSystemInfo::PopulateModelAndManufacturer(
     const ComPtr<IWbemServices>& services) {
-  static constexpr StringPiece16 query_computer_system =
-      STRING16_LITERAL("SELECT Manufacturer,Model FROM Win32_ComputerSystem");
+  static constexpr WStringPiece query_computer_system =
+      L"SELECT Manufacturer,Model FROM Win32_ComputerSystem";
 
   ComPtr<IEnumWbemClassObject> enumerator_computer_system;
-  HRESULT hr = services->ExecQuery(
-      ScopedBstr(STRING16_LITERAL("WQL")), ScopedBstr(query_computer_system),
-      WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr,
-      &enumerator_computer_system);
+  HRESULT hr =
+      services->ExecQuery(ScopedBstr(L"WQL"), ScopedBstr(query_computer_system),
+                          WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
+                          nullptr, &enumerator_computer_system);
   if (FAILED(hr) || !enumerator_computer_system.Get())
     return;
 
@@ -172,27 +172,26 @@
   ScopedVariant manufacturer;
   hr = class_object->Get(L"Manufacturer", 0, manufacturer.Receive(), 0, 0);
   if (SUCCEEDED(hr) && manufacturer.type() == VT_BSTR) {
-    WideToUTF16(V_BSTR(manufacturer.ptr()),
-                ::SysStringLen(V_BSTR(manufacturer.ptr())), &manufacturer_);
+    manufacturer_.assign(V_BSTR(manufacturer.ptr()),
+                         ::SysStringLen(V_BSTR(manufacturer.ptr())));
   }
   ScopedVariant model;
   hr = class_object->Get(L"Model", 0, model.Receive(), 0, 0);
   if (SUCCEEDED(hr) && model.type() == VT_BSTR) {
-    WideToUTF16(V_BSTR(model.ptr()), ::SysStringLen(V_BSTR(model.ptr())),
-                &model_);
+    model_.assign(V_BSTR(model.ptr()), ::SysStringLen(V_BSTR(model.ptr())));
   }
 }
 
 void WmiComputerSystemInfo::PopulateSerialNumber(
     const ComPtr<IWbemServices>& services) {
-  static constexpr StringPiece16 query_bios =
-      STRING16_LITERAL("SELECT SerialNumber FROM Win32_Bios");
+  static constexpr WStringPiece query_bios =
+      L"SELECT SerialNumber FROM Win32_Bios";
 
   ComPtr<IEnumWbemClassObject> enumerator_bios;
-  HRESULT hr = services->ExecQuery(
-      ScopedBstr(STRING16_LITERAL("WQL")), ScopedBstr(query_bios),
-      WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr,
-      &enumerator_bios);
+  HRESULT hr =
+      services->ExecQuery(ScopedBstr(L"WQL"), ScopedBstr(query_bios),
+                          WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
+                          nullptr, &enumerator_bios);
   if (FAILED(hr) || !enumerator_bios.Get())
     return;
 
@@ -205,8 +204,8 @@
   ScopedVariant serial_number;
   hr = class_obj->Get(L"SerialNumber", 0, serial_number.Receive(), 0, 0);
   if (SUCCEEDED(hr) && serial_number.type() == VT_BSTR) {
-    WideToUTF16(V_BSTR(serial_number.ptr()),
-                ::SysStringLen(V_BSTR(serial_number.ptr())), &serial_number_);
+    serial_number_.assign(V_BSTR(serial_number.ptr()),
+                          ::SysStringLen(V_BSTR(serial_number.ptr())));
   }
 }
 
diff --git a/base/win/wmi.h b/base/win/wmi.h
index e1523152ce..7949888a 100644
--- a/base/win/wmi.h
+++ b/base/win/wmi.h
@@ -24,7 +24,6 @@
 #include <wrl/client.h>
 
 #include "base/base_export.h"
-#include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 
 namespace base {
@@ -47,8 +46,8 @@
 // WMI method that you can fill with parameter values using SetParameter.
 BASE_EXPORT bool CreateWmiClassMethodObject(
     IWbemServices* wmi_services,
-    StringPiece16 class_name,
-    StringPiece16 method_name,
+    WStringPiece class_name,
+    WStringPiece method_name,
     Microsoft::WRL::ComPtr<IWbemClassObject>* class_instance);
 
 // Creates a new process from |command_line|. The advantage over CreateProcess
@@ -61,7 +60,7 @@
 // Processes created this way are children of wmiprvse.exe and run with the
 // caller credentials.
 // More info: http://msdn2.microsoft.com/en-us/library/aa394372(VS.85).aspx
-BASE_EXPORT bool WmiLaunchProcess(const string16& command_line,
+BASE_EXPORT bool WmiLaunchProcess(const std::wstring& command_line,
                                   int* process_id);
 
 // An encapsulation of information retrieved from the 'Win32_ComputerSystem' and
@@ -72,9 +71,9 @@
  public:
   static WmiComputerSystemInfo Get();
 
-  const string16& manufacturer() const { return manufacturer_; }
-  const string16& model() const { return model_; }
-  const string16& serial_number() const { return serial_number_; }
+  const std::wstring& manufacturer() const { return manufacturer_; }
+  const std::wstring& model() const { return model_; }
+  const std::wstring& serial_number() const { return serial_number_; }
 
  private:
   void PopulateModelAndManufacturer(
@@ -82,9 +81,9 @@
   void PopulateSerialNumber(
       const Microsoft::WRL::ComPtr<IWbemServices>& services);
 
-  string16 manufacturer_;
-  string16 model_;
-  string16 serial_number_;
+  std::wstring manufacturer_;
+  std::wstring model_;
+  std::wstring serial_number_;
 };
 
 }  // namespace win
diff --git a/base/win/wmi_unittest.cc b/base/win/wmi_unittest.cc
index 6c46525..438fff7 100644
--- a/base/win/wmi_unittest.cc
+++ b/base/win/wmi_unittest.cc
@@ -42,8 +42,7 @@
   ASSERT_NE(wmi_services.Get(), nullptr);
   ComPtr<IWbemClassObject> class_method = nullptr;
   EXPECT_TRUE(CreateWmiClassMethodObject(
-      wmi_services.Get(), STRING16_LITERAL("Win32_ShortcutFile"),
-      STRING16_LITERAL("Rename"), &class_method));
+      wmi_services.Get(), L"Win32_ShortcutFile", L"Rename", &class_method));
   ASSERT_NE(class_method.Get(), nullptr);
   ULONG refs = class_method.Reset();
   EXPECT_EQ(0u, refs);
@@ -54,8 +53,7 @@
 // Creates an instance of cmd which executes 'echo' and exits immediately.
 TEST_F(WMITest, TestLaunchProcess) {
   int pid = 0;
-  bool result =
-      WmiLaunchProcess(STRING16_LITERAL("cmd.exe /c echo excelent!"), &pid);
+  bool result = WmiLaunchProcess(L"cmd.exe /c echo excelent!", &pid);
   EXPECT_TRUE(result);
   EXPECT_GT(pid, 0);
 }
diff --git a/build/android/gyp/dex.py b/build/android/gyp/dex.py
index a2e17b4..6d29ac5 100755
--- a/build/android/gyp/dex.py
+++ b/build/android/gyp/dex.py
@@ -35,7 +35,7 @@
       '--multi-dex',
       action='store_true',
       help='Allow multiple dex files within output.')
-  parser.add_argument('--d8-jar-path', required=True, help='Path to D8 jar.')
+  parser.add_argument('--r8-jar-path', required=True, help='Path to R8 jar.')
   parser.add_argument(
       '--release',
       action='store_true',
@@ -250,7 +250,7 @@
 
 
 def _PerformDexing(options):
-  dex_cmd = ['java', '-jar', options.d8_jar_path, '--no-desugaring']
+  dex_cmd = ['java', '-jar', options.r8_jar_path, 'd8', '--no-desugaring']
   if options.multi_dex and options.main_dex_list_path:
     dex_cmd += ['--main-dex-list', options.main_dex_list_path]
   if options.release:
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index c94c6e6..68f765b 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1393,11 +1393,10 @@
           ]
         }
 
-        _d8_path = "//third_party/r8/lib/d8.jar"
-        inputs += [ _d8_path ]
+        inputs += [ _r8_path ]
         args += [
-          "--d8-jar-path",
-          rebase_path(_d8_path, root_build_dir),
+          "--r8-jar-path",
+          rebase_path(_r8_path, root_build_dir),
         ]
       }
     }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index e09be88..0bf082c 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8902647923806574208
\ No newline at end of file
+8902626326861029680
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 890df05..9a9205b 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-8903108260652561184
\ No newline at end of file
+8902625321346829424
\ No newline at end of file
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index ff03023..bb1c5c5 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -386,6 +386,7 @@
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java",
+  "java/src/org/chromium/chrome/browser/customtabs/CustomTabSessionHandler.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabTopBarDelegate.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabsClientFileProcessor.java",
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/address_accessory_sheet.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/address_accessory_sheet.xml
index 2d0a899..4bc6b90 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/address_accessory_sheet.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/address_accessory_sheet.xml
@@ -10,4 +10,5 @@
     android:layout_height="match_parent"
     android:layout_width="match_parent"
     android:clipToPadding="false"
-    android:paddingBottom="@dimen/keyboard_accessory_sheet_footer_trailing_margin"/>
+    android:paddingBottom="@dimen/keyboard_accessory_sheet_footer_trailing_margin"
+    android:background="@color/default_bg_color_elev_3"/>
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/credit_card_accessory_sheet.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/credit_card_accessory_sheet.xml
index 49683b0..97ee1dbd 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/credit_card_accessory_sheet.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/credit_card_accessory_sheet.xml
@@ -10,4 +10,5 @@
     android:layout_height="match_parent"
     android:layout_width="match_parent"
     android:clipToPadding="false"
-    android:paddingBottom="@dimen/keyboard_accessory_sheet_footer_trailing_margin"/>
+    android:paddingBottom="@dimen/keyboard_accessory_sheet_footer_trailing_margin"
+    android:background="@color/default_bg_color_elev_3"/>
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml
index 22b2c3d..25ade2f 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml
@@ -34,7 +34,7 @@
         android:layout_height="wrap_content"
         android:layout_gravity="start|bottom"
         android:orientation="horizontal"
-        android:background="@color/modern_primary_color">
+        android:background="@color/default_bg_color_elev_3">
 
         <ImageView
             android:id="@+id/show_keyboard"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet.xml
index 15f8885..3151229a 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet.xml
@@ -10,4 +10,5 @@
     android:layout_height="match_parent"
     android:layout_width="match_parent"
     android:clipToPadding="false"
-    android:paddingBottom="@dimen/keyboard_accessory_sheet_footer_trailing_margin"/>
+    android:paddingBottom="@dimen/keyboard_accessory_sheet_footer_trailing_margin"
+    android:background="@color/default_bg_color_elev_3"/>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionDataHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionDataHolder.java
index 7bffd3b..736e6c2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionDataHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionDataHolder.java
@@ -33,7 +33,7 @@
     private final SparseArray<SessionData> mTaskIdToSessionData = new SparseArray<>();
 
     @Nullable
-    private SessionHandler mActiveContentHandler;
+    private SessionHandler mActiveSessionHandler;
 
     @Nullable
     private Callback<CustomTabsSessionToken> mSessionDisconnectCallback;
@@ -49,7 +49,7 @@
     private static class SessionData {
         public final CustomTabsSessionToken session;
 
-        // Content handlers can reside in Activities of different types, so we need to store the
+        // Session handlers can reside in Activities of different types, so we need to store the
         // Activity class to be able to route new intents into it.
         public final Class<? extends Activity> activityClass;
 
@@ -62,25 +62,25 @@
 
     /**
      * Sets the currently active {@link SessionHandler} in focus.
-     * @param contentHandler {@link SessionHandler} to set.
+     * @param sessionHandler {@link SessionHandler} to set.
      */
-    public void setActiveHandler(@NonNull SessionHandler contentHandler) {
-        mActiveContentHandler = contentHandler;
-        CustomTabsSessionToken session = contentHandler.getSession();
+    public void setActiveHandler(@NonNull SessionHandler sessionHandler) {
+        mActiveSessionHandler = sessionHandler;
+        CustomTabsSessionToken session = sessionHandler.getSession();
         if (session == null) return;
 
-        mTaskIdToSessionData.append(contentHandler.getTaskId(),
-                new SessionData(session, contentHandler.getActivityClass()));
+        mTaskIdToSessionData.append(sessionHandler.getTaskId(),
+                new SessionData(session, sessionHandler.getActivityClass()));
         ensureSessionCleanUpOnDisconnects();
     }
 
     /**
      * Notifies that given {@link SessionHandler} no longer has focus.
      */
-    public void removeActiveHandler(SessionHandler contentHandler) {
-        if (mActiveContentHandler == contentHandler) {
-            mActiveContentHandler = null;
-        } // else this contentHandler has already been replaced.
+    public void removeActiveHandler(SessionHandler sessionHandler) {
+        if (mActiveSessionHandler == sessionHandler) {
+            mActiveSessionHandler = null;
+        } // else this sessionHandler has already been replaced.
 
         // Intentionally not removing from mTaskIdToSessionData to handle cases when the task is
         // brought to foreground by a new intent - the CCT might not be able to call
@@ -129,10 +129,10 @@
      */
     @Nullable
     public SessionHandler getActiveHandler(@Nullable CustomTabsSessionToken session) {
-        if (mActiveContentHandler == null) return null;
-        CustomTabsSessionToken activeSession = mActiveContentHandler.getSession();
+        if (mActiveSessionHandler == null) return null;
+        CustomTabsSessionToken activeSession = mActiveSessionHandler.getSession();
         if (activeSession == null || !activeSession.equals(session)) return null;
-        return mActiveContentHandler;
+        return mActiveSessionHandler;
     }
 
     @Nullable
@@ -164,8 +164,8 @@
      */
     @Deprecated
     public String getCurrentUrlForActiveBrowserSession() {
-        if (mActiveContentHandler == null) return null;
-        return mActiveContentHandler.getCurrentUrl();
+        if (mActiveSessionHandler == null) return null;
+        return mActiveSessionHandler.getCurrentUrl();
     }
 
     /**
@@ -176,8 +176,8 @@
      */
     @Deprecated
     public String getPendingUrlForActiveBrowserSession() {
-        if (mActiveContentHandler == null) return null;
-        return mActiveContentHandler.getPendingUrl();
+        if (mActiveSessionHandler == null) return null;
+        return mActiveSessionHandler.getPendingUrl();
     }
 
     private void ensureSessionCleanUpOnDisconnects() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
index 246a000..5ec213b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -4,16 +4,14 @@
 
 package org.chromium.chrome.browser.customtabs;
 
+import static org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController.FinishReason.USER_NAVIGATION;
+
 import static androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK;
 import static androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT;
 
-import static org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController.FinishReason.USER_NAVIGATION;
-
 import android.app.Activity;
-import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
-import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -24,20 +22,13 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
-import android.text.TextUtils;
 import android.util.Pair;
 import android.view.KeyEvent;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.widget.RemoteViews;
-
-import androidx.browser.customtabs.CustomTabsIntent;
-import androidx.browser.customtabs.CustomTabsService;
-import androidx.browser.customtabs.CustomTabsSessionToken;
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.CommandLine;
-import org.chromium.base.Log;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
@@ -53,10 +44,6 @@
 import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate;
 import org.chromium.chrome.browser.autofill_assistant.AutofillAssistantFacade;
 import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider.CustomTabsUiType;
-import org.chromium.chrome.browser.browserservices.Origin;
-import org.chromium.chrome.browser.browserservices.OriginVerifier;
-import org.chromium.chrome.browser.browserservices.SessionDataHolder;
-import org.chromium.chrome.browser.browserservices.SessionHandler;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabController;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabFactory;
@@ -89,18 +76,18 @@
 import org.chromium.chrome.browser.util.ColorUtils;
 import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.content_public.browser.NavigationEntry;
 import org.chromium.content_public.browser.WebContents;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import androidx.browser.customtabs.CustomTabsIntent;
+import androidx.browser.customtabs.CustomTabsSessionToken;
+
 /**
  * The activity for custom tabs. It will be launched on top of a client's task.
  */
 public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent> {
-    private static final String TAG = "CustomTabActivity";
-
     // For CustomTabs.ConnectionStatusOnReturn, see histograms.xml. Append only.
     @IntDef({ConnectionStatus.DISCONNECTED, ConnectionStatus.DISCONNECTED_KEEP_ALIVE,
             ConnectionStatus.CONNECTED, ConnectionStatus.CONNECTED_KEEP_ALIVE})
@@ -115,7 +102,6 @@
 
     private CustomTabIntentDataProvider mIntentDataProvider;
     private CustomTabsSessionToken mSession;
-    private SessionHandler mSessionHandler;
     private CustomTabBottomBarDelegate mBottomBarDelegate;
     private CustomTabActivityTabController mTabController;
     private CustomTabActivityTabProvider mTabProvider;
@@ -123,7 +109,6 @@
     private CustomTabActivityNavigationController mNavigationController;
     private CustomTabStatusBarColorProvider mCustomTabStatusBarColorProvider;
     private CustomTabToolbarCoordinator mToolbarCoordinator;
-    private SessionDataHolder mSessionDataHolder;
     private CustomTabIntentHandler mCustomTabIntentHandler;
 
     // This is to give the right package name while using the client's resources during an
@@ -314,79 +299,6 @@
             mDynamicModuleCoordinator = getComponent().resolveDynamicModuleCoordinator();
         }
 
-        mSessionHandler = new SessionHandler() {
-
-            @Override
-            public CustomTabsSessionToken getSession() {
-                return mSession;
-            }
-
-            @Override
-            public boolean updateCustomButton(int id, Bitmap bitmap, String description) {
-                CustomButtonParams params = mIntentDataProvider.getButtonParamsForId(id);
-                if (params == null) {
-                    Log.w(TAG, "Custom toolbar button with ID %d not found", id);
-                    return false;
-                }
-
-                params.update(bitmap, description);
-                if (params.showOnToolbar()) {
-                    return mToolbarCoordinator.updateCustomButton(params);
-                }
-                mBottomBarDelegate.updateBottomBarButtons(params);
-                return true;
-            }
-
-            @Override
-            public boolean updateRemoteViews(RemoteViews remoteViews, int[] clickableIDs,
-                    PendingIntent pendingIntent) {
-                return mBottomBarDelegate.updateRemoteViews(
-                        remoteViews, clickableIDs, pendingIntent);
-            }
-
-            @Override
-            @Nullable
-            public String getCurrentUrl() {
-                return getActivityTab() == null ? null : getActivityTab().getUrl();
-            }
-
-            @Override
-            @Nullable
-            public String getPendingUrl() {
-                if (getActivityTab() == null) return null;
-                if (getActivityTab().getWebContents() == null) return null;
-
-                NavigationEntry entry = getActivityTab().getWebContents().getNavigationController()
-                        .getPendingEntry();
-                return entry != null ? entry.getUrl() : null;
-            }
-
-            @Override
-            public int getTaskId() {
-                return CustomTabActivity.this.getTaskId();
-            }
-
-            @Override
-            public Class<? extends Activity> getActivityClass() {
-                return CustomTabActivity.this.getClass();
-            }
-
-            @Override
-            public boolean handleIntent(Intent intent) {
-                // This method exists only for legacy reasons, see LaunchIntentDispatcher#
-                // clearTopIntentsForCustomTabsEnabled.
-                return handleNewIntent(intent);
-            }
-
-            @Override
-            public boolean canUseReferrer(Uri referrer) {
-                String packageName = mConnection.getClientPackageNameForSession(mSession);
-                if (TextUtils.isEmpty(packageName)) return false;
-                return OriginVerifier.wasPreviouslyVerified(
-                    packageName, new Origin(referrer), CustomTabsService.RELATION_USE_AS_ORIGIN);
-            }
-        };
-
         mConnection.showSignInToastIfNecessary(mSession, getIntent());
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && useSeparateTask()) {
@@ -447,7 +359,6 @@
     @Override
     public void onStartWithNative() {
         super.onStartWithNative();
-        mSessionDataHolder.setActiveHandler(mSessionHandler);
         @TabCreationMode int mode = mTabProvider.getInitialTabCreationMode();
         boolean earlyCreatedTabIsReady =
                 (mode == TabCreationMode.HIDDEN || mode == TabCreationMode.EARLY)
@@ -456,12 +367,6 @@
     }
 
     @Override
-    public void onStopWithNative() {
-        super.onStopWithNative();
-        mSessionDataHolder.removeActiveHandler(mSessionHandler);
-    }
-
-    @Override
     protected void onDestroyInternal() {
         super.onDestroyInternal();
 
@@ -788,8 +693,8 @@
             handleFinishAndClose();
         });
         mCustomTabIntentHandler = component.resolveIntentHandler();
-        mSessionDataHolder = component.getParent().resolveSessionDataHolder();
         component.resolveCompositorContentInitializer();
+        component.resolveSessionHandler();
 
         if (mIntentDataProvider.isTrustedWebActivity()) {
             component.resolveTrustedWebActivityCoordinator();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabSessionHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabSessionHandler.java
new file mode 100644
index 0000000..0cfc8c76
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabSessionHandler.java
@@ -0,0 +1,159 @@
+// 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.customtabs;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.widget.RemoteViews;
+
+import org.chromium.base.Log;
+import org.chromium.chrome.browser.browserservices.Origin;
+import org.chromium.chrome.browser.browserservices.OriginVerifier;
+import org.chromium.chrome.browser.browserservices.SessionDataHolder;
+import org.chromium.chrome.browser.browserservices.SessionHandler;
+import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
+import org.chromium.chrome.browser.customtabs.content.CustomTabIntentHandler;
+import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator;
+import org.chromium.chrome.browser.dependency_injection.ActivityScope;
+import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
+import org.chromium.chrome.browser.lifecycle.StartStopWithNativeObserver;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.content_public.browser.NavigationEntry;
+
+import javax.inject.Inject;
+
+import androidx.browser.customtabs.CustomTabsIntent;
+import androidx.browser.customtabs.CustomTabsService;
+import androidx.browser.customtabs.CustomTabsSessionToken;
+import dagger.Lazy;
+
+/**
+ * Implements {@link SessionHandler} for the given instance of Custom Tab activity; registers and
+ * unregisters itself in {@link SessionDataHolder}.
+ */
+@ActivityScope
+public class CustomTabSessionHandler implements SessionHandler, StartStopWithNativeObserver {
+
+    private static final String TAG = "CctSessionHandler";
+
+    private final CustomTabIntentDataProvider mIntentDataProvider;
+    private final CustomTabActivityTabProvider mTabProvider;
+    private final Lazy<CustomTabToolbarCoordinator> mToolbarCoordinator;
+    private final Lazy<CustomTabBottomBarDelegate> mBottomBarDelegate;
+    private final CustomTabIntentHandler mIntentHandler;
+    private final CustomTabsConnection mConnection;
+    private final SessionDataHolder mSessionDataHolder;
+    private final Activity mActivity;
+
+    @Inject
+    public CustomTabSessionHandler(CustomTabIntentDataProvider intentDataProvider,
+            CustomTabActivityTabProvider tabProvider,
+            Lazy<CustomTabToolbarCoordinator> toolbarCoordinator,
+            Lazy<CustomTabBottomBarDelegate> bottomBarDelegate,
+            CustomTabIntentHandler intentHandler,
+            CustomTabsConnection connection,
+            Activity activity,
+            ActivityLifecycleDispatcher lifecycleDispatcher,
+            SessionDataHolder sessionDataHolder) {
+        mIntentDataProvider = intentDataProvider;
+        mTabProvider = tabProvider;
+        mToolbarCoordinator = toolbarCoordinator;
+        mBottomBarDelegate = bottomBarDelegate;
+        mIntentHandler = intentHandler;
+        mConnection = connection;
+        mActivity = activity;
+        mSessionDataHolder = sessionDataHolder;
+        lifecycleDispatcher.register(this);
+    }
+
+    @Override
+    public void onStartWithNative() {
+        mSessionDataHolder.setActiveHandler(this);
+    }
+
+    @Override
+    public void onStopWithNative() {
+        mSessionDataHolder.removeActiveHandler(this);
+    }
+
+    @Override
+    public CustomTabsSessionToken getSession() {
+        return mIntentDataProvider.getSession();
+    }
+
+    @Override
+    public boolean updateCustomButton(int id, Bitmap bitmap, String description) {
+        CustomButtonParams params = mIntentDataProvider.getButtonParamsForId(id);
+        if (params == null) {
+            Log.w(TAG, "Custom toolbar button with ID %d not found", id);
+            return false;
+        }
+
+        params.update(bitmap, description);
+        if (params.showOnToolbar()) {
+            return mToolbarCoordinator.get().updateCustomButton(params);
+        }
+        mBottomBarDelegate.get().updateBottomBarButtons(params);
+        return true;
+    }
+
+    @Override
+    public boolean updateRemoteViews(RemoteViews remoteViews, int[] clickableIDs,
+            PendingIntent pendingIntent) {
+        return mBottomBarDelegate.get().updateRemoteViews(remoteViews, clickableIDs, pendingIntent);
+    }
+
+    @Override
+    @Nullable
+    public String getCurrentUrl() {
+        Tab tab = mTabProvider.getTab();
+        return tab == null ? null : tab.getUrl();
+    }
+
+    @Override
+    @Nullable
+    public String getPendingUrl() {
+        Tab tab = mTabProvider.getTab();
+        if (tab == null || tab.getWebContents() == null) return null;
+
+        NavigationEntry entry = tab.getWebContents().getNavigationController()
+                .getPendingEntry();
+        return entry != null ? entry.getUrl() : null;
+    }
+
+    @Override
+    public int getTaskId() {
+        return mActivity.getTaskId();
+    }
+
+    @Override
+    public Class<? extends Activity> getActivityClass() {
+        return mActivity.getClass();
+    }
+
+    @Override
+    public boolean handleIntent(Intent intent) {
+        // This method exists only for legacy reasons, see LaunchIntentDispatcher#
+        // clearTopIntentsForCustomTabsEnabled.
+        CustomTabIntentDataProvider dataProvider = new CustomTabIntentDataProvider(intent,
+                mActivity, CustomTabsIntent.COLOR_SCHEME_LIGHT);
+
+        return mIntentHandler.onNewIntent(dataProvider);
+    }
+
+    @Override
+    public boolean canUseReferrer(Uri referrer) {
+        CustomTabsSessionToken session = mIntentDataProvider.getSession();
+        String packageName = mConnection.getClientPackageNameForSession(session);
+        if (TextUtils.isEmpty(packageName)) return false;
+        return OriginVerifier.wasPreviouslyVerified(
+                packageName, new Origin(referrer), CustomTabsService.RELATION_USE_AS_ORIGIN);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java
index 9edac88..1aba9d4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java
@@ -8,13 +8,14 @@
 import org.chromium.chrome.browser.customtabs.CustomTabActivityLifecycleUmaTracker;
 import org.chromium.chrome.browser.customtabs.CustomTabBottomBarDelegate;
 import org.chromium.chrome.browser.customtabs.CustomTabCompositorContentInitializer;
+import org.chromium.chrome.browser.customtabs.CustomTabSessionHandler;
 import org.chromium.chrome.browser.customtabs.CustomTabStatusBarColorProvider;
 import org.chromium.chrome.browser.customtabs.CustomTabTabPersistencePolicy;
-import org.chromium.chrome.browser.customtabs.content.CustomTabIntentHandler;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabController;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabFactory;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
+import org.chromium.chrome.browser.customtabs.content.CustomTabIntentHandler;
 import org.chromium.chrome.browser.customtabs.dynamicmodule.DynamicModuleCoordinator;
 import org.chromium.chrome.browser.customtabs.dynamicmodule.DynamicModuleToolbarController;
 import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator;
@@ -45,6 +46,7 @@
     CustomTabStatusBarColorProvider resolveCustomTabStatusBarColorProvider();
     CustomTabToolbarCoordinator resolveToolbarCoordinator();
     CustomTabCompositorContentInitializer resolveCompositorContentInitializer();
+    CustomTabSessionHandler resolveSessionHandler();
 
     CustomTabTabPersistencePolicy resolveTabPersistencePolicy(); // For testing
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallMessageHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallMessageHandler.java
index f451e7c..e7d495b5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallMessageHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallMessageHandler.java
@@ -10,6 +10,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
+import android.os.Build;
 import android.text.TextUtils;
 
 import org.chromium.base.BuildInfo;
@@ -127,9 +128,26 @@
      * Returns true if we should open the dialer straight away.
      */
     private static boolean shouldOpenDialer() {
-        // On Q and above, we never open the dialer directly. On pre-Q, we always open the dialer
-        // directly.
-        return !BuildInfo.isAtLeastQ() && FeatureUtilities.isClickToCallOpenDialerDirectlyEnabled();
+        if (!FeatureUtilities.isClickToCallOpenDialerDirectlyEnabled()) {
+            return false;
+        }
+
+        // On Android Q and above, we never open the dialer directly.
+        if (BuildInfo.isAtLeastQ()) {
+            return false;
+        }
+
+        // On Android N and below, we always open the dialer. If device is locked, we also show a
+        // notification. We can listen to ACTION_USER_PRESENT and remove this notification when
+        // device is unlocked.
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+            return true;
+        }
+
+        // On Android O and P, we open dialer only when device is unlocked since we cannot listen to
+        // ACTION_USER_PRESENT.
+        return DeviceConditions.isCurrentlyScreenOnAndUnlocked(
+                ContextUtils.getApplicationContext());
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
index 91882b8..37077f7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -31,10 +31,13 @@
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.AccountTrackerService;
 import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.components.signin.identitymanager.ClearAccountsAction;
 import org.chromium.components.signin.identitymanager.CoreAccountInfo;
 import org.chromium.components.signin.identitymanager.IdentityManager;
+import org.chromium.components.signin.identitymanager.PrimaryAccountMutator;
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.signin.metrics.SigninReason;
+import org.chromium.components.signin.metrics.SignoutDelete;
 import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.components.sync.AndroidSyncSettings;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
@@ -191,6 +194,7 @@
     private final Context mContext;
     private final AccountTrackerService mAccountTrackerService;
     private final IdentityManager mIdentityManager;
+    private final PrimaryAccountMutator mPrimaryAccountMutator;
     private final AndroidSyncSettings mAndroidSyncSettings;
     private final ObserverList<SignInStateObserver> mSignInStateObservers = new ObserverList<>();
     private final ObserverList<SignInAllowedObserver> mSignInAllowedObservers =
@@ -245,6 +249,7 @@
         mNativeSigninManagerAndroid = nativeSigninManagerAndroid;
         mAccountTrackerService = accountTrackerService;
         mIdentityManager = identityManager;
+        mPrimaryAccountMutator = identityManager.getPrimaryAccountMutator();
         mAndroidSyncSettings = androidSyncSettings;
 
         mSigninAllowedByPolicy =
@@ -402,6 +407,7 @@
      * @param activity The activity used to launch UI prompts, or null for a forced signin.
      * @param callback Optional callback for when the sign-in process is finished.
      */
+    // TODO(crbug.com/1002056) SigninManager.Signin should use CoreAccountInfo as a parameter.
     public void signIn(
             Account account, @Nullable Activity activity, @Nullable SignInCallback callback) {
         if (account == null) {
@@ -431,6 +437,7 @@
     /**
      * Same as above but retrieves the Account object for the given accountName.
      */
+    // TODO(crbug.com/1002056) SigninManager.Signin should use CoreAccountInfo as a parameter.
     public void signIn(String accountName, @Nullable final Activity activity,
             @Nullable final SignInCallback callback) {
         AccountManagerFacade.get().getAccountFromName(
@@ -481,8 +488,13 @@
         // This method should be called at most once per sign-in flow.
         assert mSignInState != null;
 
-        if (!SigninManagerJni.get().setPrimaryAccount(
-                    mNativeSigninManagerAndroid, mSignInState.mAccount.name)) {
+        // TODO(crbug.com/1002056) When changing SignIn signature to use CoreAccountInfo, change the
+        // following line to use it instead of retrieving from IdentityManager.
+        if (!mPrimaryAccountMutator.setPrimaryAccount(
+                    mIdentityManager
+                            .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
+                                    mSignInState.mAccount.name)
+                            .getId())) {
             Log.w(TAG, "Failed to set the PrimaryAccount in IdentityManager, aborting signin");
             abortSignIn();
             return;
@@ -524,7 +536,7 @@
      * Implements {@link IdentityManager.Observer}: take action when primary account is set.
      * Simply verify that the request is ongoing (mSignInState != null), as only SigninManager
      * should update IdentityManager. This is triggered by the call to
-     * SigninManagerJni.get().setPrimaryAccount.
+     * PrimaryAccountMutator.setPrimaryAccount
      */
     @VisibleForTesting
     @Override
@@ -616,7 +628,11 @@
 
         // User data will be wiped in disableSyncAndWipeData(), called from
         // onPrimaryAccountcleared().
-        SigninManagerJni.get().signOut(mNativeSigninManagerAndroid, signoutSource);
+        mPrimaryAccountMutator.clearPrimaryAccount(ClearAccountsAction.DEFAULT, signoutSource,
+                // Always use IGNORE_METRIC for the profile deletion argument. Chrome
+                // Android has just a single-profile which is never deleted upon
+                // sign-out.
+                SignoutDelete.IGNORE_METRIC);
     }
 
     /**
@@ -768,10 +784,6 @@
 
         boolean isForceSigninEnabled(long nativeSigninManagerAndroid);
 
-        boolean setPrimaryAccount(long nativeSigninManagerAndroid, String username);
-
-        void signOut(long nativeSigninManagerAndroid, @SignoutReason int reason);
-
         void clearLastSignedInUser(long nativeSigninManagerAndroid);
 
         void logInSignedInUser(long nativeSigninManagerAndroid);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
index d58e391..150d4efb 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
@@ -15,6 +15,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.MockitoAnnotations.initMocks;
@@ -36,6 +37,7 @@
 import org.chromium.components.signin.identitymanager.CoreAccountId;
 import org.chromium.components.signin.identitymanager.CoreAccountInfo;
 import org.chromium.components.signin.identitymanager.IdentityManager;
+import org.chromium.components.signin.identitymanager.PrimaryAccountMutator;
 import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.components.sync.AndroidSyncSettings;
 
@@ -53,6 +55,7 @@
 
     private AccountTrackerService mAccountTrackerService;
     private IdentityManager mIdentityManager;
+    private PrimaryAccountMutator mPrimaryAccountMutator;
     private SigninManager mSigninManager;
     private CoreAccountInfo mAccount;
 
@@ -66,7 +69,10 @@
 
         mAccountTrackerService = mock(AccountTrackerService.class);
 
-        mIdentityManager = new IdentityManager(0 /* nativeIdentityManager */);
+        mPrimaryAccountMutator = mock(PrimaryAccountMutator.class);
+
+        mIdentityManager =
+                spy(new IdentityManager(0 /* nativeIdentityManager */, mPrimaryAccountMutator));
 
         AndroidSyncSettings androidSyncSettings = mock(AndroidSyncSettings.class);
 
@@ -75,7 +81,7 @@
                 androidSyncSettings);
 
         mAccount = new CoreAccountInfo(new CoreAccountId("gaia-id-user"),
-                AccountManagerFacade.createAccountFromName("user@domain.com"));
+                AccountManagerFacade.createAccountFromName("user@domain.com"), "gaia-id-user");
     }
 
     @Test
@@ -186,8 +192,8 @@
             mIdentityManager.onPrimaryAccountCleared(mAccount);
             return null;
         })
-                .when(mNativeMock)
-                .signOut(anyLong(), anyInt());
+                .when(mPrimaryAccountMutator)
+                .clearPrimaryAccount(anyInt(), anyInt(), anyInt());
 
         mSigninManager.signOut(SignoutReason.SIGNOUT_TEST);
         assertTrue(mSigninManager.isOperationInProgress());
@@ -202,19 +208,25 @@
 
     @Test
     public void callbackNotifiedOnSignin() {
+        CoreAccountInfo account = new CoreAccountInfo(new CoreAccountId("test_at_gmail.com"),
+                new Account("test@gmail.com", AccountManagerFacade.GOOGLE_ACCOUNT_TYPE),
+                "test_at_gmail.com");
+
         // No need to seed accounts to the native code.
         doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts();
         // Request that policy is loaded. It will pause sign-in until onPolicyCheckedBeforeSignIn is
         // invoked.
         doNothing().when(mNativeMock).fetchAndApplyCloudPolicy(anyLong(), any(), any());
 
-        doReturn(true).when(mNativeMock).setPrimaryAccount(anyLong(), any());
+        doReturn(account)
+                .when(mIdentityManager)
+                .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(any());
+        doReturn(true).when(mPrimaryAccountMutator).setPrimaryAccount(any());
         doNothing().when(mNativeMock).logInSignedInUser(anyLong());
 
         mSigninManager.onFirstRunCheckDone(); // Allow sign-in.
 
-        Account account = new Account("test@gmail.com", AccountManagerFacade.GOOGLE_ACCOUNT_TYPE);
-        mSigninManager.signIn(account, null, null);
+        mSigninManager.signIn(account.getAccount(), null, null);
         assertTrue(mSigninManager.isOperationInProgress());
         AtomicInteger callCount = new AtomicInteger(0);
         mSigninManager.runAfterOperationInProgress(callCount::incrementAndGet);
diff --git a/chrome/browser/android/customtabs/detached_resource_request.cc b/chrome/browser/android/customtabs/detached_resource_request.cc
index 2b94bc8..0e90fa0 100644
--- a/chrome/browser/android/customtabs/detached_resource_request.cc
+++ b/chrome/browser/android/customtabs/detached_resource_request.cc
@@ -79,7 +79,8 @@
   resource_request->url = url_;
   // The referrer is stripped if it's not set properly initially.
   resource_request->referrer = net::URLRequestJob::ComputeReferrerForPolicy(
-      referrer_policy, site_for_cookies_, url_);
+      referrer_policy, site_for_cookies_,
+      url::Origin::Create(site_for_cookies_), url_);
   resource_request->referrer_policy = referrer_policy;
   resource_request->site_for_cookies = site_for_cookies_;
   resource_request->request_initiator = url::Origin::Create(site_for_cookies_);
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc
index e128237..f9a6e7d2 100644
--- a/chrome/browser/android/signin/signin_manager_android.cc
+++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -161,35 +161,6 @@
                              java_signin_manager_);
 }
 
-jboolean SigninManagerAndroid::SetPrimaryAccount(
-    JNIEnv* env,
-    const JavaParamRef<jstring>& username) {
-  DVLOG(1) << "SigninManagerAndroid::SetPrimaryAccount";
-
-  auto account =
-      identity_manager_
-          ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
-              base::android::ConvertJavaStringToUTF8(env, username));
-  DCHECK(account.has_value());
-  auto* account_mutator = identity_manager_->GetPrimaryAccountMutator();
-  return account_mutator->SetPrimaryAccount(account->account_id);
-}
-
-void SigninManagerAndroid::SignOut(JNIEnv* env,
-                                   jint signoutReason) {
-  auto* account_mutator = identity_manager_->GetPrimaryAccountMutator();
-
-  // GetPrimaryAccountMutator() returns nullptr on ChromeOS only.
-  DCHECK(account_mutator);
-  account_mutator->ClearPrimaryAccount(
-      signin::PrimaryAccountMutator::ClearAccountsAction::kDefault,
-      static_cast<signin_metrics::ProfileSignout>(signoutReason),
-      // Always use IGNORE_METRIC for the profile deletion argument. Chrome
-      // Android has just a single-profile which is never deleted upon
-      // sign-out.
-      signin_metrics::SignoutDelete::IGNORE_METRIC);
-}
-
 void SigninManagerAndroid::ClearLastSignedInUser(JNIEnv* env) {
   ClearLastSignedInUserForProfile(profile_);
 }
diff --git a/chrome/browser/android/signin/signin_manager_android.h b/chrome/browser/android/signin/signin_manager_android.h
index 1c8f5a3..fc1c3df7 100644
--- a/chrome/browser/android/signin/signin_manager_android.h
+++ b/chrome/browser/android/signin/signin_manager_android.h
@@ -45,15 +45,6 @@
 
   base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
 
-  // Indicates that the user has made the choice to sign-in. |username|
-  // contains the email address of the account to use as primary.
-  jboolean SetPrimaryAccount(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jstring>& username);
-
-  void SignOut(JNIEnv* env,
-               jint signoutReason);
-
   void LogInSignedInUser(JNIEnv* env);
 
   void ClearLastSignedInUser(JNIEnv* env);
diff --git a/chrome/browser/apps/app_service/app_service_proxy.cc b/chrome/browser/apps/app_service/app_service_proxy.cc
index cf26ed2..e8c5fc7 100644
--- a/chrome/browser/apps/app_service/app_service_proxy.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy.cc
@@ -86,6 +86,22 @@
       icon_coalescer_(&inner_icon_loader_),
       outer_icon_loader_(&icon_coalescer_,
                          apps::IconCache::GarbageCollectionPolicy::kEager) {
+  Initialize(profile, connector);
+}
+
+AppServiceProxy::~AppServiceProxy() = default;
+
+void AppServiceProxy::ReInitializeForTesting(
+    Profile* profile,
+    service_manager::Connector* connector) {
+  // Some test code creates a profile and profile-linked services, like the App
+  // Service without linking to the correct connector. To work around that, we
+  // issue a second Initialize call to set the connector.
+  Initialize(profile, connector);
+}
+
+void AppServiceProxy::Initialize(Profile* profile,
+                                 service_manager::Connector* connector) {
   if (!profile) {
     return;
   }
@@ -125,8 +141,6 @@
   }
 }
 
-AppServiceProxy::~AppServiceProxy() = default;
-
 apps::mojom::AppServicePtr& AppServiceProxy::AppService() {
   return app_service_;
 }
diff --git a/chrome/browser/apps/app_service/app_service_proxy.h b/chrome/browser/apps/app_service/app_service_proxy.h
index fbdac3a9..9ddf038 100644
--- a/chrome/browser/apps/app_service/app_service_proxy.h
+++ b/chrome/browser/apps/app_service/app_service_proxy.h
@@ -47,6 +47,9 @@
 
   ~AppServiceProxy() override;
 
+  void ReInitializeForTesting(Profile* profile,
+                              service_manager::Connector* connector);
+
   apps::mojom::AppServicePtr& AppService();
   apps::AppRegistryCache& AppRegistryCache();
 
@@ -141,6 +144,8 @@
 
   AppServiceProxy(Profile* profile, service_manager::Connector* connector);
 
+  void Initialize(Profile* profile, service_manager::Connector* connector);
+
   void AddAppIconSource(Profile* profile);
 
   // KeyedService overrides.
diff --git a/chrome/browser/apps/app_service/extension_apps.cc b/chrome/browser/apps/app_service/extension_apps.cc
index 78437581..a9ad356 100644
--- a/chrome/browser/apps/app_service/extension_apps.cc
+++ b/chrome/browser/apps/app_service/extension_apps.cc
@@ -420,7 +420,7 @@
       break;
     case extensions::UnloadedExtensionReason::UNINSTALL:
       readiness = apps::mojom::Readiness::kUninstalledByUser;
-      return;
+      break;
     default:
       return;
   }
diff --git a/chrome/browser/apps/user_type_filter_unittest.cc b/chrome/browser/apps/user_type_filter_unittest.cc
index 5717ef42..4bb54f5 100644
--- a/chrome/browser/apps/user_type_filter_unittest.cc
+++ b/chrome/browser/apps/user_type_filter_unittest.cc
@@ -26,7 +26,7 @@
   auto root = std::make_unique<base::DictionaryValue>();
   base::ListValue filter;
   for (const auto& user_type : user_types)
-    filter.GetList().push_back(base::Value(user_type));
+    filter.Append(base::Value(user_type));
   root->SetKey(kKeyUserType, std::move(filter));
   return root;
 }
@@ -123,8 +123,8 @@
 TEST_F(UserTypeFilterTest, DefaultFilter) {
   auto profile = CreateProfile();
   base::ListValue default_filter;
-  default_filter.GetList().push_back(base::Value(kUserTypeUnmanaged));
-  default_filter.GetList().push_back(base::Value(kUserTypeGuest));
+  default_filter.Append(base::Value(kUserTypeUnmanaged));
+  default_filter.Append(base::Value(kUserTypeGuest));
 
   // Unmanaged user.
   EXPECT_TRUE(MatchDefault(profile, default_filter));
diff --git a/chrome/browser/autofill/automated_tests/cache_replayer_unittest.cc b/chrome/browser/autofill/automated_tests/cache_replayer_unittest.cc
index 403f18f..6ea658d 100644
--- a/chrome/browser/autofill/automated_tests/cache_replayer_unittest.cc
+++ b/chrome/browser/autofill/automated_tests/cache_replayer_unittest.cc
@@ -179,8 +179,7 @@
     // Populate json dict node that contains Autofill Server requests per URL.
     if (urls_dict.find(url) == urls_dict.end())
       urls_dict[url] = std::make_unique<Value>(Value::ListStorage());
-    urls_dict[url]->GetList().push_back(
-        Value(std::move(request_response_node)));
+    urls_dict[url]->Append(Value(std::move(request_response_node)));
   }
 
   // Make json dict node that contains requests per domain.
@@ -285,7 +284,7 @@
   std::string invalid_request_url = GetParam();
   urls_dict[invalid_request_url] =
       std::make_unique<Value>(Value::ListStorage());
-  urls_dict[invalid_request_url]->GetList().push_back(
+  urls_dict[invalid_request_url]->Append(
       Value(std::move(request_response_node)));
 
   // Make json dict node that contains requests per domain.
diff --git a/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc b/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc
index 7041afc..33fc1c3 100644
--- a/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc
+++ b/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc
@@ -43,7 +43,7 @@
   base::ListValue out;
   out.GetList().reserve(src.size());
   for (base::StringPiece str : src)
-    out.GetList().push_back(base::Value(str));
+    out.Append(base::Value(str));
   return out;
 }
 
diff --git a/chrome/browser/browser_switcher/browser_switcher_browsertest.cc b/chrome/browser/browser_switcher/browser_switcher_browsertest.cc
index 99606ea..bef8fe8 100644
--- a/chrome/browser/browser_switcher/browser_switcher_browsertest.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_browsertest.cc
@@ -86,12 +86,12 @@
 
   base::ListValue params;
   for (size_t i = 1; i < cmd_line.argv().size(); i++)
-    params.GetList().emplace_back(NativeToUTF8(cmd_line.argv()[i]));
+    params.Append(NativeToUTF8(cmd_line.argv()[i]));
   SetPolicy(&map, policy::key::kAlternativeBrowserParameters,
             std::make_unique<base::Value>(std::move(params)));
 
   base::ListValue sitelist;
-  sitelist.GetList().emplace_back("example.com");
+  sitelist.Append("example.com");
   SetPolicy(&map, policy::key::kBrowserSwitcherUrlList,
             std::make_unique<base::Value>(std::move(sitelist)));
 
diff --git a/chrome/browser/browser_switcher/browser_switcher_policy_migrator.cc b/chrome/browser/browser_switcher/browser_switcher_policy_migrator.cc
index 6bfdaf0..a1b3249a 100644
--- a/chrome/browser/browser_switcher/browser_switcher_policy_migrator.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_policy_migrator.cc
@@ -38,7 +38,7 @@
 void StringToList(base::Value* val) {
   std::string str = val->GetString();
   *val = base::Value(base::Value::Type::LIST);
-  val->GetList().push_back(base::Value(std::move(str)));
+  val->Append(base::Value(std::move(str)));
 }
 
 }  // namespace
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs.cc b/chrome/browser/browser_switcher/browser_switcher_prefs.cc
index 44d0ac2..e95e216 100644
--- a/chrome/browser/browser_switcher/browser_switcher_prefs.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_prefs.cc
@@ -33,7 +33,7 @@
                     const std::vector<std::string>& rules) {
   base::ListValue rules_val;
   for (const auto& url : rules)
-    rules_val.GetList().push_back(base::Value(url));
+    rules_val.Append(base::Value(url));
   prefs->Set(pref_name, rules_val);
 }
 
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
index 870bed8..360310c 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
@@ -419,7 +419,7 @@
   policy::PolicyMap policies;
   EnableBrowserSwitcher(&policies);
   auto url_list = std::make_unique<base::ListValue>();
-  url_list->GetList().emplace_back("*");
+  url_list->Append("*");
   SetPolicy(&policies, policy::key::kBrowserSwitcherUrlList,
             std::move(url_list));
   SetPolicy(&policies, policy::key::kBrowserSwitcherExternalGreylistUrl,
@@ -654,21 +654,21 @@
   SetPolicy(&policies, policy::key::kAlternativeBrowserPath,
             std::make_unique<base::Value>("IExplore.exe"));
   auto alt_params = std::make_unique<base::ListValue>();
-  alt_params->GetList().push_back(base::Value("--bogus-flag"));
+  alt_params->Append(base::Value("--bogus-flag"));
   SetPolicy(&policies, policy::key::kAlternativeBrowserParameters,
             std::move(alt_params));
   SetPolicy(&policies, policy::key::kBrowserSwitcherChromePath,
             std::make_unique<base::Value>("chrome.exe"));
   auto chrome_params = std::make_unique<base::ListValue>();
-  chrome_params->GetList().push_back(base::Value("--force-dark-mode"));
+  chrome_params->Append(base::Value("--force-dark-mode"));
   SetPolicy(&policies, policy::key::kBrowserSwitcherChromeParameters,
             std::move(chrome_params));
   auto url_list = std::make_unique<base::ListValue>();
-  url_list->GetList().push_back(base::Value("example.com"));
+  url_list->Append(base::Value("example.com"));
   SetPolicy(&policies, policy::key::kBrowserSwitcherUrlList,
             std::move(url_list));
   auto greylist = std::make_unique<base::ListValue>();
-  greylist->GetList().push_back(base::Value("foo.example.com"));
+  greylist->Append(base::Value("foo.example.com"));
   SetPolicy(&policies, policy::key::kBrowserSwitcherUrlGreylist,
             std::move(greylist));
   policy_provider().UpdateChromePolicy(policies);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 5ca6076..1e9fd93d 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1923,7 +1923,7 @@
   base::ListValue* list = update.Get();
   base::Value value(origin.Serialize());
   if (!base::Contains(list->GetList(), value))
-    list->GetList().push_back(std::move(value));
+    list->Append(std::move(value));
 }
 
 bool ChromeContentBrowserClient::IsFileAccessAllowed(
@@ -4653,22 +4653,14 @@
     RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(
         content::BrowserContext* browser_context,
         NonNetworkURLLoaderFactoryMap* factories) {
-#if BUILDFLAG(ENABLE_EXTENSIONS) || defined(OS_CHROMEOS)
+#if BUILDFLAG(ENABLE_EXTENSIONS)
   DCHECK(browser_context);
   DCHECK(factories);
-#if BUILDFLAG(ENABLE_EXTENSIONS)
   factories->emplace(
       extensions::kExtensionScheme,
       extensions::CreateExtensionServiceWorkerScriptURLLoaderFactory(
           browser_context));
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
-#if defined(OS_CHROMEOS)
-  Profile* profile = Profile::FromBrowserContext(browser_context);
-  factories->emplace(content::kExternalFileScheme,
-                     std::make_unique<chromeos::ExternalFileURLLoaderFactory>(
-                         profile, content::ChildProcessHost::kInvalidUniqueID));
-#endif  // defined(OS_CHROMEOS)
-#endif  // BUILDFLAG(ENABLE_EXTENSIONS) || defined(OS_CHROMEOS)
 }
 
 namespace {
@@ -4968,7 +4960,7 @@
       network_service);
 }
 
-network::mojom::NetworkContextPtr
+mojo::Remote<network::mojom::NetworkContext>
 ChromeContentBrowserClient::CreateNetworkContext(
     content::BrowserContext* context,
     bool in_memory,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 6bb5019..a219479 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -498,7 +498,7 @@
       override;
   void OnNetworkServiceCreated(
       network::mojom::NetworkService* network_service) override;
-  network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       content::BrowserContext* context,
       bool in_memory,
       const base::FilePath& relative_partition_path) override;
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 13604ed..f53e5a5 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1310,6 +1310,8 @@
     "login/saml/in_session_password_change_manager.h",
     "login/saml/password_expiry_notification.cc",
     "login/saml/password_expiry_notification.h",
+    "login/saml/public_saml_url_fetcher.cc",
+    "login/saml/public_saml_url_fetcher.h",
     "login/saml/saml_offline_signin_limiter.cc",
     "login/saml/saml_offline_signin_limiter.h",
     "login/saml/saml_offline_signin_limiter_factory.cc",
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_util.h b/chrome/browser/chromeos/arc/policy/arc_policy_util.h
index 238a18f..96f6f78 100644
--- a/chrome/browser/chromeos/arc/policy/arc_policy_util.h
+++ b/chrome/browser/chromeos/arc/policy/arc_policy_util.h
@@ -57,7 +57,7 @@
 
 // Returns set of packages requested to install from |arc_policy|. |arc_policy|
 // has JSON blob format, see
-// https://www.chromium.org/administrators/policy-list-3#ArcPolicy
+// https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ArcPolicy
 std::set<std::string> GetRequestedPackagesFromArcPolicy(
     const std::string& arc_policy);
 
diff --git a/chrome/browser/chromeos/crostini/ansible/ansible_management_service.cc b/chrome/browser/chromeos/crostini/ansible/ansible_management_service.cc
index a88169f7..393abb0 100644
--- a/chrome/browser/chromeos/crostini/ansible/ansible_management_service.cc
+++ b/chrome/browser/chromeos/crostini/ansible/ansible_management_service.cc
@@ -7,7 +7,9 @@
 #include "base/logging.h"
 #include "base/no_destructor.h"
 #include "chrome/browser/chromeos/crostini/crostini_manager_factory.h"
+#include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 
@@ -48,6 +50,10 @@
   }
 };
 
+chromeos::CiceroneClient* GetCiceroneClient() {
+  return chromeos::DBusThreadManager::Get()->GetCiceroneClient();
+}
+
 }  // namespace
 
 AnsibleManagementService* AnsibleManagementService::GetForProfile(
@@ -123,8 +129,71 @@
 }
 
 void AnsibleManagementService::ApplyAnsiblePlaybookToDefaultContainer(
-    const std::string& playbook) {
-  NOTIMPLEMENTED();
+    const std::string& playbook,
+    base::OnceCallback<void(bool success)> callback) {
+  if (!GetCiceroneClient()->IsApplyAnsiblePlaybookProgressSignalConnected()) {
+    // Technically we could still start the application, but we wouldn't be able
+    // to detect when the application completes, successfully or otherwise.
+    LOG(ERROR)
+        << "Attempted to apply playbook when progress signal not connected.";
+    std::move(callback).Run(/*success=*/false);
+    return;
+  }
+
+  DCHECK(ansible_playbook_application_finished_callback_.is_null());
+  ansible_playbook_application_finished_callback_ = std::move(callback);
+
+  vm_tools::cicerone::ApplyAnsiblePlaybookRequest request;
+  request.set_owner_id(CryptohomeIdForProfile(profile_));
+  request.set_vm_name(std::move(kCrostiniDefaultContainerName));
+  request.set_container_name(std::move(kCrostiniDefaultContainerName));
+  request.set_playbook(std::move(playbook));
+
+  GetCiceroneClient()->ApplyAnsiblePlaybook(
+      std::move(request),
+      base::BindOnce(&AnsibleManagementService::OnApplyAnsiblePlaybook,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AnsibleManagementService::OnApplyAnsiblePlaybook(
+    base::Optional<vm_tools::cicerone::ApplyAnsiblePlaybookResponse> response) {
+  if (!response) {
+    LOG(ERROR) << "Failed to apply Ansible playbook. Empty response.";
+    std::move(ansible_playbook_application_finished_callback_)
+        .Run(/*success=*/false);
+    return;
+  }
+
+  if (response->status() ==
+      vm_tools::cicerone::ApplyAnsiblePlaybookResponse::FAILED) {
+    LOG(ERROR) << "Failed to apply Ansible playbook: "
+               << response->failure_reason();
+    std::move(ansible_playbook_application_finished_callback_)
+        .Run(/*success=*/false);
+    return;
+  }
+
+  VLOG(1) << "Ansible playbook application has been started successfully";
+  // Waiting for Ansible playbook application progress being reported.
+}
+
+void AnsibleManagementService::OnApplyAnsiblePlaybookProgress(
+    vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::Status status) {
+  switch (status) {
+    case vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::SUCCEEDED:
+      std::move(ansible_playbook_application_finished_callback_)
+          .Run(/*success=*/true);
+      break;
+    case vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::FAILED:
+      std::move(ansible_playbook_application_finished_callback_)
+          .Run(/*success=*/false);
+      break;
+    case vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::IN_PROGRESS:
+      // TODO(okalitova): Report Ansible playbook application progress.
+      break;
+    default:
+      NOTREACHED();
+  }
 }
 
 }  // namespace crostini
diff --git a/chrome/browser/chromeos/crostini/ansible/ansible_management_service.h b/chrome/browser/chromeos/crostini/ansible/ansible_management_service.h
index ba5e5a6b..c9f7734 100644
--- a/chrome/browser/chromeos/crostini/ansible/ansible_management_service.h
+++ b/chrome/browser/chromeos/crostini/ansible/ansible_management_service.h
@@ -29,10 +29,14 @@
   explicit AnsibleManagementService(Profile* profile);
   ~AnsibleManagementService() override;
 
+  // |callback| is called once Ansible installation is finished.
   void InstallAnsibleInDefaultContainer(
       base::OnceCallback<void(bool success)> callback);
 
-  void ApplyAnsiblePlaybookToDefaultContainer(const std::string& playbook);
+  // |callback| is called once Ansible playbook application is finished.
+  void ApplyAnsiblePlaybookToDefaultContainer(
+      const std::string& playbook,
+      base::OnceCallback<void(bool success)> callback);
 
   // LinuxPackageOperationProgressObserver:
   void OnInstallLinuxPackageProgress(const std::string& vm_name,
@@ -44,12 +48,23 @@
                                   UninstallPackageProgressStatus status,
                                   int progress_percent) override;
 
+  void OnApplyAnsiblePlaybookProgress(
+      vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::Status status);
+
  private:
   void OnInstallAnsibleInDefaultContainer(CrostiniResult result);
 
+  // Callback for
+  // CrostiniAnsibleManagementService::ApplyAnsiblePlaybookToDefaultContainer
+  void OnApplyAnsiblePlaybook(
+      base::Optional<vm_tools::cicerone::ApplyAnsiblePlaybookResponse>
+          response);
+
   Profile* profile_;
   base::OnceCallback<void(bool success)>
       ansible_installation_finished_callback_;
+  base::OnceCallback<void(bool success)>
+      ansible_playbook_application_finished_callback_;
   base::WeakPtrFactory<AnsibleManagementService> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(AnsibleManagementService);
diff --git a/chrome/browser/chromeos/crostini/ansible/ansible_management_service_unittest.cc b/chrome/browser/chromeos/crostini/ansible/ansible_management_service_unittest.cc
index d6993a1..5ba744c 100644
--- a/chrome/browser/chromeos/crostini/ansible/ansible_management_service_unittest.cc
+++ b/chrome/browser/chromeos/crostini/ansible/ansible_management_service_unittest.cc
@@ -22,11 +22,13 @@
     fake_cicerone_client_ = static_cast<chromeos::FakeCiceroneClient*>(
         chromeos::DBusThreadManager::Get()->GetCiceroneClient());
     profile_ = std::make_unique<TestingProfile>();
+    crostini_manager_ = CrostiniManager::GetForProfile(profile_.get());
     ansible_management_service_ =
-        std::make_unique<AnsibleManagementService>(profile_.get());
+        AnsibleManagementService::GetForProfile(profile_.get());
   }
   ~AnsibleManagementServiceTest() override {
-    ansible_management_service_.reset();
+    ansible_management_service_->Shutdown();
+    crostini_manager_->Shutdown();
     profile_.reset();
     chromeos::DBusThreadManager::Shutdown();
   }
@@ -35,7 +37,7 @@
   Profile* profile() { return profile_.get(); }
 
   AnsibleManagementService* ansible_management_service() {
-    return ansible_management_service_.get();
+    return ansible_management_service_;
   }
 
   void SendSucceededInstallSignal() {
@@ -49,11 +51,25 @@
     fake_cicerone_client_->InstallLinuxPackageProgress(signal);
   }
 
+  void SendSucceededApplicationSignal() {
+    vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal signal;
+    signal.set_owner_id(CryptohomeIdForProfile(profile()));
+    signal.set_vm_name(kCrostiniDefaultVmName);
+    signal.set_container_name(kCrostiniDefaultContainerName);
+    signal.set_status(
+        vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::SUCCEEDED);
+
+    fake_cicerone_client_->NotifyApplyAnsiblePlaybookProgress(signal);
+  }
+
   content::BrowserTaskEnvironment task_environment_;
   std::unique_ptr<TestingProfile> profile_;
-  std::unique_ptr<AnsibleManagementService> ansible_management_service_;
+  CrostiniManager* crostini_manager_;
+  AnsibleManagementService* ansible_management_service_;
   base::MockCallback<base::OnceCallback<void(bool)>>
       ansible_installation_finished_mock_callback_;
+  base::MockCallback<base::OnceCallback<void(bool)>>
+      ansible_playbook_application_finished_mock_callback_;
   // Owned by chromeos::DBusThreadManager
   chromeos::FakeCiceroneClient* fake_cicerone_client_;
 
@@ -93,4 +109,41 @@
   base::RunLoop().RunUntilIdle();
 }
 
+TEST_F(AnsibleManagementServiceTest,
+       ApplyAnsiblePlaybookToDefaultContainerSuccess) {
+  vm_tools::cicerone::ApplyAnsiblePlaybookResponse response;
+  response.set_status(
+      vm_tools::cicerone::ApplyAnsiblePlaybookResponse::STARTED);
+  fake_cicerone_client_->set_apply_ansible_playbook_response(response);
+
+  EXPECT_CALL(ansible_playbook_application_finished_mock_callback_, Run(true))
+      .Times(1);
+
+  ansible_management_service()->ApplyAnsiblePlaybookToDefaultContainer(
+      /*playbook=*/"",
+      ansible_playbook_application_finished_mock_callback_.Get());
+
+  // Actually starts applying Ansible playbook.
+  base::RunLoop().RunUntilIdle();
+
+  SendSucceededApplicationSignal();
+}
+
+TEST_F(AnsibleManagementServiceTest,
+       ApplyAnsiblePlaybookToDefaultContainerFail) {
+  vm_tools::cicerone::ApplyAnsiblePlaybookResponse response;
+  response.set_status(vm_tools::cicerone::ApplyAnsiblePlaybookResponse::FAILED);
+  fake_cicerone_client_->set_apply_ansible_playbook_response(response);
+
+  EXPECT_CALL(ansible_playbook_application_finished_mock_callback_, Run(false))
+      .Times(1);
+
+  ansible_management_service()->ApplyAnsiblePlaybookToDefaultContainer(
+      /*playbook=*/"",
+      ansible_playbook_application_finished_mock_callback_.Get());
+
+  // Actually starts applying Ansible playbook.
+  base::RunLoop().RunUntilIdle();
+}
+
 }  // namespace crostini
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc
index 92063d8..bb2a546 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -2126,6 +2126,16 @@
   }
 }
 
+void CrostiniManager::OnApplyAnsiblePlaybookProgress(
+    const vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal& signal) {
+  if (signal.owner_id() != owner_id_)
+    return;
+
+  // TODO(okalitova): Add an observer.
+  AnsibleManagementService::GetForProfile(profile_)
+      ->OnApplyAnsiblePlaybookProgress(signal.status());
+}
+
 void CrostiniManager::OnUninstallPackageOwningFile(
     CrostiniResultCallback callback,
     base::Optional<vm_tools::cicerone::UninstallPackageOwningFileResponse>
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.h b/chrome/browser/chromeos/crostini/crostini_manager.h
index 1cabdb9..ad5381a 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.h
+++ b/chrome/browser/chromeos/crostini/crostini_manager.h
@@ -467,6 +467,9 @@
       override;
   void OnPendingAppListUpdates(
       const vm_tools::cicerone::PendingAppListUpdatesSignal& signal) override;
+  void OnApplyAnsiblePlaybookProgress(
+      const vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal& signal)
+      override;
 
   // chromeos::PowerManagerClient::Observer overrides:
   void SuspendImminent(power_manager::SuspendImminent::Reason reason) override;
diff --git a/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc b/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc
index c67a9dc..8f28536 100644
--- a/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc
+++ b/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc
@@ -46,6 +46,31 @@
 #define MAYBE_TestDeviceRequisition TestDeviceRequisition
 #endif
 
+// Disabled on debug build due to flakiness: https://crbug.com/997685.
+#if !defined(NDEBUG)
+#define MAYBE_TestAcceptEula DISABLED_TestAcceptEula
+#define MAYBE_TestDemoModeAcceptArcTos DISABLED_TestDemoModeAcceptArcTos
+#define MAYBE_TestDemoModeAcceptEula DISABLED_TestDemoModeAcceptEula
+#define MAYBE_TestDemoModeOfflineNetwork DISABLED_TestDemoModeOfflineNetwork
+#define MAYBE_TestDemoModePreferences DISABLED_TestDemoModePreferences
+#define MAYBE_TestEnableDemoMode DISABLED_TestEnableDemoMode
+#define MAYBE_TestLeaveWelcomeScreen DISABLED_TestLeaveWelcomeScreen
+#define MAYBE_TestSwitchLanguageIME DISABLED_TestSwitchLanguageIME
+#define MAYBE_TestLeaveWelcomeScreen DISABLED_TestLeaveWelcomeScreen
+#define MAYBE_TestSkipHIDDetection DISABLED_TestSkipHIDDetection
+#else
+#define MAYBE_TestAcceptEula TestAcceptEula
+#define MAYBE_TestDemoModeAcceptArcTos TestDemoModeAcceptArcTos
+#define MAYBE_TestDemoModeAcceptEula TestDemoModeAcceptEula
+#define MAYBE_TestDemoModeOfflineNetwork TestDemoModeOfflineNetwork
+#define MAYBE_TestDemoModePreferences TestDemoModePreferences
+#define MAYBE_TestEnableDemoMode TestEnableDemoMode
+#define MAYBE_TestLeaveWelcomeScreen TestLeaveWelcomeScreen
+#define MAYBE_TestSwitchLanguageIME TestSwitchLanguageIME
+#define MAYBE_TestLeaveWelcomeScreen TestLeaveWelcomeScreen
+#define MAYBE_TestSkipHIDDetection TestSkipHIDDetection
+#endif
+
 namespace chromeos {
 
 // This test case will use
@@ -186,13 +211,13 @@
 };
 
 // Check that configuration lets correctly pass Welcome screen.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestLeaveWelcomeScreen) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, MAYBE_TestLeaveWelcomeScreen) {
   LoadConfiguration();
   OobeScreenWaiter(NetworkScreenView::kScreenId).Wait();
 }
 
 // Check that language and input methods are set correctly.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestSwitchLanguageIME) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, MAYBE_TestSwitchLanguageIME) {
   LoadConfiguration();
   OobeScreenWaiter(NetworkScreenView::kScreenId).Wait();
 
@@ -214,20 +239,21 @@
 }
 
 // Check that configuration lets correctly start Demo mode setup.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestEnableDemoMode) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, MAYBE_TestEnableDemoMode) {
   LoadConfiguration();
   OobeScreenWaiter(DemoPreferencesScreenView::kScreenId).Wait();
 }
 
 // Check that configuration lets correctly pass through demo preferences.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDemoModePreferences) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, MAYBE_TestDemoModePreferences) {
   LoadConfiguration();
   OobeScreenWaiter(NetworkScreenView::kScreenId).Wait();
 }
 
 // Check that configuration lets correctly use offline demo mode on network
 // screen.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDemoModeOfflineNetwork) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTest,
+                       MAYBE_TestDemoModeOfflineNetwork) {
   LoadConfiguration();
   OobeScreenWaiter(DemoPreferencesScreenView::kScreenId).Wait();
   SimulateOfflineEnvironment();
@@ -236,7 +262,7 @@
 
 // Check that configuration lets correctly use offline demo mode on EULA
 // screen.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDemoModeAcceptEula) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, MAYBE_TestDemoModeAcceptEula) {
   LoadConfiguration();
   OobeScreenWaiter(DemoPreferencesScreenView::kScreenId).Wait();
   SimulateOfflineEnvironment();
@@ -245,7 +271,7 @@
 
 // Check that configuration lets correctly use offline demo mode on ARC++ ToS
 // screen.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDemoModeAcceptArcTos) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, MAYBE_TestDemoModeAcceptArcTos) {
   LoadConfiguration();
   OobeScreenWaiter(DemoPreferencesScreenView::kScreenId).Wait();
   SimulateOfflineEnvironment();
@@ -281,7 +307,7 @@
 }
 
 // Check that when configuration has ONC and EULA, we get to update screen.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestAcceptEula) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, MAYBE_TestAcceptEula) {
   UpdateEngineClient::Status status;
   status.status = UpdateEngineClient::UPDATE_STATUS_DOWNLOADING;
   status.download_progress = 0.1;
@@ -331,7 +357,7 @@
 
 // Check that HID detection screen is really skipped and rest of configuration
 // is applied.
-IN_PROC_BROWSER_TEST_F(OobeConfigurationTestNoHID, TestSkipHIDDetection) {
+IN_PROC_BROWSER_TEST_F(OobeConfigurationTestNoHID, MAYBE_TestSkipHIDDetection) {
   LoadConfiguration();
   OobeScreenWaiter(NetworkScreenView::kScreenId).Wait();
 }
diff --git a/chrome/browser/chromeos/login/saml/public_saml_url_fetcher.cc b/chrome/browser/chromeos/login/saml/public_saml_url_fetcher.cc
new file mode 100644
index 0000000..623c33e2
--- /dev/null
+++ b/chrome/browser/chromeos/login/saml/public_saml_url_fetcher.cc
@@ -0,0 +1,126 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/saml/public_saml_url_fetcher.h"
+
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/arc/arc_optin_uma.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/policy/device_local_account.h"
+#include "chrome/browser/chromeos/policy/dm_token_storage.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chrome/browser/net/system_network_context_manager.h"
+#include "chromeos/tpm/install_attributes.h"
+#include "components/account_id/account_id.h"
+#include "components/policy/core/common/cloud/device_management_service.h"
+#include "components/policy/core/common/cloud/dm_auth.h"
+#include "components/policy/core/common/cloud/dmserver_job_configurations.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "url/gurl.h"
+
+namespace em = enterprise_management;
+namespace {
+std::string GetDeviceId() {
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
+  return connector->GetInstallAttributes()->GetDeviceId();
+}
+
+std::string GetAccountId(std::string user_id) {
+  std::vector<policy::DeviceLocalAccount> device_local_accounts =
+      policy::GetDeviceLocalAccounts(chromeos::CrosSettings::Get());
+  for (auto account : device_local_accounts) {
+    if (account.user_id == user_id) {
+      return account.account_id;
+    }
+  }
+  return std::string();
+}
+}  // namespace
+
+namespace chromeos {
+PublicSamlUrlFetcher::PublicSamlUrlFetcher(AccountId account_id)
+    : account_id_(GetAccountId(account_id.GetUserEmail())) {}
+
+PublicSamlUrlFetcher::~PublicSamlUrlFetcher() = default;
+
+std::string PublicSamlUrlFetcher::GetRedirectUrl() {
+  return redirect_url_;
+}
+
+bool PublicSamlUrlFetcher::FetchSucceeded() {
+  return fetch_succeeded_;
+}
+
+void PublicSamlUrlFetcher::Fetch(base::OnceClosure callback) {
+  DCHECK(!callback_);
+  callback_ = std::move(callback);
+  policy::DeviceManagementService* service =
+      g_browser_process->platform_part()
+          ->browser_policy_connector_chromeos()
+          ->device_management_service();
+  std::unique_ptr<policy::DMServerJobConfiguration> config = std::make_unique<
+      policy::DMServerJobConfiguration>(
+      service,
+      policy::DeviceManagementService::JobConfiguration::TYPE_REQUEST_SAML_URL,
+      GetDeviceId(), /*critical=*/false,
+      policy::DMAuth::FromDMToken(chromeos::DeviceSettingsService::Get()
+                                      ->policy_data()
+                                      ->request_token()),
+      /*oauth_token=*/base::nullopt,
+      g_browser_process->system_network_context_manager()
+          ->GetSharedURLLoaderFactory(),
+      base::Bind(&PublicSamlUrlFetcher::OnPublicSamlUrlReceived,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  em::PublicSamlUserRequest* saml_url_request =
+      config->request()->mutable_public_saml_user_request();
+  saml_url_request->set_account_id(account_id_);
+  fetch_request_job_ = service->CreateJob(std::move(config));
+}
+
+void PublicSamlUrlFetcher::OnPublicSamlUrlReceived(
+    policy::DeviceManagementService::Job* job,
+    policy::DeviceManagementStatus dm_status,
+    int net_error,
+    const enterprise_management::DeviceManagementResponse& response) {
+  VLOG(1) << "Public SAML url response received. DM Status: " << dm_status;
+  fetch_request_job_.reset();
+  std::string user_id;
+
+  switch (dm_status) {
+    case policy::DM_STATUS_SUCCESS: {
+      if (!response.has_public_saml_user_response()) {
+        LOG(WARNING) << "Invalid public SAML url response.";
+        break;
+      }
+      const em::PublicSamlUserResponse& saml_url_response =
+          response.public_saml_user_response();
+
+      if (!saml_url_response.has_saml_parameters()) {
+        LOG(WARNING) << "Invalid public SAML url response.";
+        break;
+      }
+      // Fetch has succeeded.
+      fetch_succeeded_ = true;
+      const em::SamlParametersProto& saml_params =
+          saml_url_response.saml_parameters();
+      redirect_url_ = saml_params.auth_redirect_url();
+      break;
+    }
+    default: {  // All other error cases
+      LOG(ERROR) << "Fetching public SAML url failed. DM Status: " << dm_status;
+      break;
+    }
+  }
+  std::move(callback_).Run();
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/saml/public_saml_url_fetcher.h b/chrome/browser/chromeos/login/saml/public_saml_url_fetcher.h
new file mode 100644
index 0000000..8b8a990
--- /dev/null
+++ b/chrome/browser/chromeos/login/saml/public_saml_url_fetcher.h
@@ -0,0 +1,67 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SAML_PUBLIC_SAML_URL_FETCHER_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_SAML_PUBLIC_SAML_URL_FETCHER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/account_id/account_id.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#include "components/policy/core/common/cloud/device_management_service.h"
+
+namespace enterprise_management {
+class DeviceManagementResponse;
+}  // namespace enterprise_management
+
+namespace chromeos {
+
+// This class handles sending request for public SAML session URL to DM
+// server, waits for the response and retrieves the redirect URL from it.
+class PublicSamlUrlFetcher {
+ public:
+  explicit PublicSamlUrlFetcher(AccountId account_id);
+  ~PublicSamlUrlFetcher();
+
+  // Sends request to the DM server, gets and checks the response and
+  // calls the callback.
+  void Fetch(base::OnceClosure callback);
+  std::string GetRedirectUrl();
+  bool FetchSucceeded();
+
+ private:
+  // Response from DM server. Calls the stored FetchCallback or initiates the
+  // SAML flow.
+  void OnPublicSamlUrlReceived(
+      policy::DeviceManagementService::Job* job,
+      policy::DeviceManagementStatus dm_status,
+      int net_error,
+      const enterprise_management::DeviceManagementResponse& response);
+
+  // Account ID, added to the DM server request.
+  std::string account_id_;
+
+  // Indicates whether fetching the redirect URL was successful.
+  bool fetch_succeeded_ = false;
+
+  // Job that sends request to the DM server.
+  std::unique_ptr<policy::DeviceManagementService::Job> fetch_request_job_;
+
+  // The redirect URL.
+  std::string redirect_url_;
+
+  // Called at the end of Fetch().
+  base::OnceClosure callback_;
+  base::WeakPtrFactory<PublicSamlUrlFetcher> weak_ptr_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(PublicSamlUrlFetcher);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_SAML_PUBLIC_SAML_URL_FETCHER_H_
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
index d31e2a4..eae4e07 100644
--- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
+++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -417,6 +417,17 @@
                   POLICY_SOURCE_CLOUD, std::move(rules), nullptr);
   }
 
+  if (policy.has_device_login_screen_webusb_allow_devices_for_urls()) {
+    const em::DeviceLoginScreenWebUsbAllowDevicesForUrlsProto& container(
+        policy.device_login_screen_webusb_allow_devices_for_urls());
+    if (container.has_device_login_screen_webusb_allow_devices_for_urls()) {
+      SetJsonDevicePolicy(
+          key::kDeviceLoginScreenWebUsbAllowDevicesForUrls,
+          container.device_login_screen_webusb_allow_devices_for_urls(),
+          policies);
+    }
+  }
+
   if (policy.has_saml_login_authentication_type()) {
     const em::SamlLoginAuthenticationTypeProto& container(
         policy.saml_login_authentication_type());
diff --git a/chrome/browser/component_updater/metadata_table_chromeos.cc b/chrome/browser/component_updater/metadata_table_chromeos.cc
index 64a22e7..916a2c3 100644
--- a/chrome/browser/component_updater/metadata_table_chromeos.cc
+++ b/chrome/browser/component_updater/metadata_table_chromeos.cc
@@ -183,7 +183,7 @@
   base::Value item(base::Value::Type::DICTIONARY);
   item.SetKey(kMetadataContentItemHashedUserIdKey, base::Value(hashed_user_id));
   item.SetKey(kMetadataContentItemComponentKey, base::Value(component_name));
-  installed_items_.GetList().emplace_back(std::move(item));
+  installed_items_.Append(std::move(item));
 }
 
 bool MetadataTable::DeleteItem(const std::string& hashed_user_id,
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
index c6ab4e3..2848ef3 100644
--- a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
+++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
@@ -571,7 +571,7 @@
 
     base::Value client(client_id);
     DCHECK(!base::Contains(clients->GetList(), client));
-    clients->GetList().push_back(std::move(client));
+    clients->Append(std::move(client));
   }
 
   if (!newly_added) {
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc
index ec89514..f799123 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.cc
+++ b/chrome/browser/devtools/device/devtools_android_bridge.cc
@@ -166,8 +166,8 @@
       base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
                  base::Unretained(this)));
   base::Value target_discovery(base::Value::Type::LIST);
-  target_discovery.GetList().emplace_back(kChromeDiscoveryURL);
-  target_discovery.GetList().emplace_back(kNodeDiscoveryURL);
+  target_discovery.Append(kChromeDiscoveryURL);
+  target_discovery.Append(kNodeDiscoveryURL);
   profile->GetPrefs()->SetDefaultPrefValue(prefs::kDevToolsTCPDiscoveryConfig,
                                            std::move(target_discovery));
   CreateDeviceProviders();
diff --git a/chrome/browser/devtools/serialize_host_descriptions.cc b/chrome/browser/devtools/serialize_host_descriptions.cc
index d1bdc91..054acd9 100644
--- a/chrome/browser/devtools/serialize_host_descriptions.cc
+++ b/chrome/browser/devtools/serialize_host_descriptions.cc
@@ -27,8 +27,7 @@
   auto child_it = children.find(root);
   if (child_it != children.end()) {
     for (base::DictionaryValue* child : child_it->second) {
-      children_list->base::Value::GetList().push_back(
-          Serialize(child_key, child, children));
+      children_list->base::Value::Append(Serialize(child_key, child, children));
     }
   }
 
@@ -98,8 +97,7 @@
 
   base::ListValue list_value;
   for (auto* root : roots) {
-    list_value.base::Value::GetList().push_back(
-        Serialize(child_key, root, children));
+    list_value.base::Value::Append(Serialize(child_key, root, children));
   }
   return list_value;
 }
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
index 2b44f3e..60e9da0d 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
@@ -255,7 +255,7 @@
   for (auto& component : components->GetList()) {
     base::Value row(base::Value::Type::DICTIONARY);
     row.SetKey("row", std::move(component));
-    rows.GetList().emplace_back(std::move(row));
+    rows.Append(std::move(row));
   }
 
   address_components.SetKey("components", std::move(rows));
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc
index 4ed224a..a96cf26 100644
--- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc
@@ -83,8 +83,8 @@
     function->set_has_callback(true);
 
     auto args = std::make_unique<base::Value>(base::Value::Type::LIST);
-    args->GetList().emplace_back(
-        base::Value::BlobStorage(app_id.begin(), app_id.end()));
+    args->Append(
+        base::Value(base::Value::BlobStorage(app_id.begin(), app_id.end())));
 
     if (!extension_function_test_utils::RunFunction(
             function.get(), base::ListValue::From(std::move(args)), browser(),
@@ -210,7 +210,7 @@
     dict.emplace("tabId", std::make_unique<base::Value>(tab_id_));
     dict.emplace("origin", std::make_unique<base::Value>(app_id));
     auto args = std::make_unique<base::Value>(base::Value::Type::LIST);
-    args->GetList().emplace_back(std::move(dict));
+    args->Append(base::Value(std::move(dict)));
     auto args_list = base::ListValue::From(std::move(args));
 
     extension_function_test_utils::RunFunction(
diff --git a/chrome/browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc b/chrome/browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc
index 6d91223..997fed5 100644
--- a/chrome/browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc
+++ b/chrome/browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc
@@ -255,7 +255,7 @@
   // 2. Test writing behavior.
   {
     base::Value value(base::Value::Type::LIST);
-    value.GetList().push_back(base::Value(true));
+    value.Append(base::Value(true));
     cache_delegate->UpdateRules(extension1_->id(), std::move(value));
   }
   EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
@@ -302,7 +302,7 @@
   auto cache_delegate = std::make_unique<RulesCacheDelegate>(
       RulesCacheDelegate::Type::kEphemeral, false);
   base::Value value(base::Value::Type::LIST);
-  value.GetList().push_back(base::Value(true));
+  value.Append(base::Value(true));
   cache_delegate->UpdateRules(extension1_->id(), std::move(value));
   content::RunAllTasksUntilIdle();
   TestingValueStore* store = env_.GetExtensionSystem()->value_store();
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
index cf68ed7..62b206b 100644
--- a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
+++ b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
@@ -80,7 +80,7 @@
   list.GetList().reserve(controls.size());
   for (const auto& control : controls) {
     std::unique_ptr<base::Value> control_value = control.ToValue();
-    list.GetList().push_back(std::move(*control_value));
+    list.Append(std::move(*control_value));
   }
 
   std::string json;
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
index 0e2a4d3..2694d31 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -932,7 +932,7 @@
   scoped_refptr<DownloadsOpenFunction> scoped_open(new DownloadsOpenFunction());
   scoped_open->set_user_gesture(true);
   base::Value args_list(base::Value::Type::LIST);
-  args_list.GetList().emplace_back(static_cast<int>(download_item->GetId()));
+  args_list.Append(static_cast<int>(download_item->GetId()));
   scoped_open->SetArgs(std::move(args_list));
   scoped_open->set_browser_context(current_browser()->profile());
   scoped_open->set_extension(extension());
diff --git a/chrome/browser/extensions/api/messaging/native_process_launcher.cc b/chrome/browser/extensions/api/messaging/native_process_launcher.cc
index edfdcbf..e8480b4 100644
--- a/chrome/browser/extensions/api/messaging/native_process_launcher.cc
+++ b/chrome/browser/extensions/api/messaging/native_process_launcher.cc
@@ -258,7 +258,7 @@
     base::Value args(base::Value::Type::LIST);
     args.GetList().reserve(reconnect_command_line.argv().size());
     for (const auto& arg : reconnect_command_line.argv()) {
-      args.GetList().emplace_back(arg);
+      args.Append(arg);
     }
     std::string encoded_reconnect_command;
     bool success =
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
index d06e55a..4fa4eac 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
@@ -379,7 +379,7 @@
   wrapper.SetKey(name, std::move(event));
 
   base::Value event_list(base::Value::Type::LIST);
-  event_list.GetList().push_back(std::move(wrapper));
+  event_list.Append(std::move(wrapper));
 
   client_->UploadRealtimeReport(
       policy::RealtimeReportingJobConfiguration::BuildReport(
diff --git a/chrome/browser/extensions/convert_web_app.cc b/chrome/browser/extensions/convert_web_app.cc
index 882dd14..e506394 100644
--- a/chrome/browser/extensions/convert_web_app.cc
+++ b/chrome/browser/extensions/convert_web_app.cc
@@ -73,9 +73,9 @@
         continue;
 
       if (acceptsUTF8[0] == '.') {
-        file_extensions.GetList().push_back(base::Value(acceptsUTF8.substr(1)));
+        file_extensions.Append(base::Value(acceptsUTF8.substr(1)));
       } else {
-        mime_types.GetList().push_back(base::Value(acceptsUTF8));
+        mime_types.Append(base::Value(acceptsUTF8));
       }
     }
 
diff --git a/chrome/browser/extensions/extension_web_ui_unittest.cc b/chrome/browser/extensions/extension_web_ui_unittest.cc
index 38a5b10..65c7e47 100644
--- a/chrome/browser/extensions/extension_web_ui_unittest.cc
+++ b/chrome/browser/extensions/extension_web_ui_unittest.cc
@@ -183,7 +183,7 @@
       base::Value newtab(base::Value::Type::DICTIONARY);
       newtab.SetKey("entry", base::Value(newtab_url.spec()));
       newtab.SetKey("active", base::Value(true));
-      newtab_list.GetList().push_back(std::move(newtab));
+      newtab_list.Append(std::move(newtab));
     }
     {
       base::Value newtab(base::Value::Type::DICTIONARY);
@@ -191,7 +191,7 @@
           "entry",
           base::Value(extension->GetResourceURL("oldtab.html").spec()));
       newtab.SetKey("active", base::Value(true));
-      newtab_list.GetList().push_back(std::move(newtab));
+      newtab_list.Append(std::move(newtab));
     }
 
     all_overrides->SetKey("newtab", std::move(newtab_list));
diff --git a/chrome/browser/extensions/external_pref_loader.cc b/chrome/browser/extensions/external_pref_loader.cc
index f4b5108..5c744bb 100644
--- a/chrome/browser/extensions/external_pref_loader.cc
+++ b/chrome/browser/extensions/external_pref_loader.cc
@@ -326,8 +326,7 @@
   std::unique_ptr<base::ListValue> default_user_types;
   if (options_ & USE_USER_TYPE_PROFILE_FILTER) {
     default_user_types = std::make_unique<base::ListValue>();
-    default_user_types->GetList().push_back(
-        base::Value(apps::kUserTypeUnmanaged));
+    default_user_types->Append(base::Value(apps::kUserTypeUnmanaged));
   }
 
   // For each file read the json description & build the proper
diff --git a/chrome/browser/media/router/mojo/media_sink_service_status.cc b/chrome/browser/media/router/mojo/media_sink_service_status.cc
index 2786d74..9edba9b 100644
--- a/chrome/browser/media/router/mojo/media_sink_service_status.cc
+++ b/chrome/browser/media/router/mojo/media_sink_service_status.cc
@@ -96,7 +96,7 @@
   for (const auto& sinks_it : sinks) {
     base::ListValue list;
     for (const auto& inner_sink : sinks_it.second)
-      list.GetList().push_back(ToValue(inner_sink));
+      list.Append(ToValue(inner_sink));
     dict.SetKey(sinks_it.first, std::move(list));
   }
   return dict;
@@ -112,7 +112,7 @@
     base::Value list(base::Value::Type::LIST);
     for (const auto& inner_sink : sinks_it.second) {
       std::string sink_id = inner_sink.sink().id();
-      list.GetList().push_back(base::Value(TruncateSinkId(sink_id)));
+      list.Append(base::Value(TruncateSinkId(sink_id)));
     }
     dict.SetKey(sinks_it.first, std::move(list));
   }
diff --git a/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc
index 04f39b43..72ff0e8 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc
+++ b/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc
@@ -75,7 +75,7 @@
       image_value.SetIntKey("width", image->size->width());
       image_value.SetIntKey("height", image->size->height());
     }
-    image_list.GetList().push_back(std::move(image_value));
+    image_list.Append(std::move(image_value));
   }
   return image_list;
 }
@@ -170,7 +170,7 @@
 
     Value status_list(Value::Type::DICTIONARY);
     status_list.SetKey("status", Value(Value::Type::LIST));
-    status_list.FindKey("status")->GetList().push_back(std::move(status_value));
+    status_list.FindKey("status")->Append(std::move(status_value));
     controller_->SetMediaStatus(std::move(status_list));
   }
 
diff --git a/chrome/browser/media/webrtc/webrtc_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_log_uploader.cc
index 118028e..1b386f4a 100644
--- a/chrome/browser/media/webrtc/webrtc_log_uploader.cc
+++ b/chrome/browser/media/webrtc/webrtc_log_uploader.cc
@@ -544,7 +544,7 @@
     }
   }
 
-  // Write the capture time and log ID to the log list file. Leave the upload
+  // Write the log ID and capture time to the log list file. Leave the upload
   // time and report ID empty.
   contents += ",," + local_log_id + "," +
               base::NumberToString(base::Time::Now().ToDoubleT()) + '\n';
diff --git a/chrome/browser/media/webrtc/webrtc_log_uploader.h b/chrome/browser/media/webrtc/webrtc_log_uploader.h
index b1475a1..ea558ca 100644
--- a/chrome/browser/media/webrtc/webrtc_log_uploader.h
+++ b/chrome/browser/media/webrtc/webrtc_log_uploader.h
@@ -166,18 +166,19 @@
   // Append information (upload time, report ID and local ID) about a log to a
   // log list file, limited to |kLogListLimitLines| entries. This list is used
   // for viewing the logs under chrome://webrtc-logs, see WebRtcLogUploadList.
-  // The list has the format
-  // upload_time,report_id,local_id
-  // upload_time,report_id,local_id
-  // etc.
-  // where each line represents a log. "upload_time" is the time when the log
-  // was uploaded in Unix time. "report_id" is the ID reported back by the
-  // server. "local_id" is the ID for the locally stored log. It's the time
-  // stored in Unix time and it's also used as file name.
-  // AddLocallyStoredLogInfoToUploadListFile() will first be called,
-  // "upload_time" and "report_id" is the left empty in the entry written to the
-  // list file. If uploading is successful, AddUploadedLogInfoToUploadListFile()
-  // is called and those empty items are filled out.
+  // The list has the format:
+  //   [upload_time],[report_id],[local_id],[capture_time]
+  // Each line represents a log.
+  // * |upload_time| is the time when the log was uploaded in Unix time.
+  // * |report_id| is the ID reported back by the server.
+  // * |local_id| is the ID for the locally stored log. It's the time stored
+  //   in Unix time and it's also used as file name.
+  // * |capture_time| is the Unix time when the log was captured.
+  // AddLocallyStoredLogInfoToUploadListFile() will first be called.
+  // |upload_time| and |report_id| will be left empty in the entry written to
+  // the list file. If uploading is successful,
+  // AddUploadedLogInfoToUploadListFile() will be called and those empty fields
+  // will be filled out.
   // Must be called on the FILE thread.
   void AddLocallyStoredLogInfoToUploadListFile(
       const base::FilePath& upload_list_path,
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc
index 40019887..465949f 100644
--- a/chrome/browser/net/profile_network_context_service.cc
+++ b/chrome/browser/net/profile_network_context_service.cc
@@ -219,14 +219,14 @@
 
 ProfileNetworkContextService::~ProfileNetworkContextService() {}
 
-network::mojom::NetworkContextPtr
+mojo::Remote<network::mojom::NetworkContext>
 ProfileNetworkContextService::CreateNetworkContext(
     bool in_memory,
     const base::FilePath& relative_partition_path) {
-  network::mojom::NetworkContextPtr network_context;
+  mojo::Remote<network::mojom::NetworkContext> network_context;
 
   content::GetNetworkService()->CreateNetworkContext(
-      MakeRequest(&network_context),
+      network_context.BindNewPipeAndPassReceiver(),
       CreateNetworkContextParams(in_memory, relative_partition_path));
 
   if ((!in_memory && !profile_->IsOffTheRecord())) {
diff --git a/chrome/browser/net/profile_network_context_service.h b/chrome/browser/net/profile_network_context_service.h
index 0178384..ad43b67 100644
--- a/chrome/browser/net/profile_network_context_service.h
+++ b/chrome/browser/net/profile_network_context_service.h
@@ -21,6 +21,7 @@
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_member.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/net_buildflags.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 
@@ -45,7 +46,7 @@
   // Creates a NetworkContext for the BrowserContext, using the specified
   // parameters. An empty |relative_partition_path| corresponds to the main
   // network context.
-  network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       bool in_memory,
       const base::FilePath& relative_partition_path);
 
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
index 7f8536a..4092e1f 100644
--- a/chrome/browser/net/system_network_context_manager.cc
+++ b/chrome/browser/net/system_network_context_manager.cc
@@ -308,7 +308,7 @@
 
 network::mojom::NetworkContext* SystemNetworkContextManager::GetContext() {
   if (!network_service_network_context_ ||
-      network_service_network_context_.encountered_error()) {
+      !network_service_network_context_.is_connected()) {
     // This should call into OnNetworkServiceCreated(), which will re-create
     // the network service, if needed. There's a chance that it won't be
     // invoked, if the NetworkContext has encountered an error but the
@@ -597,8 +597,9 @@
 
   // The system NetworkContext must be created first, since it sets
   // |primary_network_context| to true.
+  network_service_network_context_.reset();
   network_service->CreateNetworkContext(
-      MakeRequest(&network_service_network_context_),
+      network_service_network_context_.BindNewPipeAndPassReceiver(),
       CreateNetworkContextParams());
 
   mojo::PendingRemote<network::mojom::NetworkContextClient> client_remote;
diff --git a/chrome/browser/net/system_network_context_manager.h b/chrome/browser/net/system_network_context_manager.h
index 1d1b129..28af1033 100644
--- a/chrome/browser/net/system_network_context_manager.h
+++ b/chrome/browser/net/system_network_context_manager.h
@@ -15,6 +15,7 @@
 #include "chrome/browser/net/proxy_config_monitor.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_member.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/host_resolver.mojom-forward.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/network_service.mojom-forward.h"
@@ -170,7 +171,7 @@
 
   // NetworkContext using the network service, if the network service is
   // enabled. nullptr, otherwise.
-  network::mojom::NetworkContextPtr network_service_network_context_;
+  mojo::Remote<network::mojom::NetworkContext> network_service_network_context_;
 
   // URLLoaderFactory backed by the NetworkContext returned by GetContext(), so
   // consumers don't all need to create their own factory.
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
index 73b5cbc..3b6e11d 100644
--- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
@@ -121,6 +121,13 @@
     "PageLoad.Clients.NoServiceWorker2.DocumentTiming."
     "NavigationToLoadEventFired.search";
 
+const char kHistogramServiceWorkerFirstContentfulPaintDocs[] =
+    "PageLoad.Clients.ServiceWorker2.PaintTiming."
+    "NavigationToFirstContentfulPaint.docs";
+const char kHistogramNoServiceWorkerFirstContentfulPaintDocs[] =
+    "PageLoad.Clients.NoServiceWorker2.PaintTiming."
+    "NavigationToFirstContentfulPaint.docs";
+
 }  // namespace internal
 
 namespace {
@@ -129,6 +136,10 @@
   return url.host_piece() == "inbox.google.com";
 }
 
+bool IsDocsSite(const GURL& url) {
+  return url.host_piece() == "docs.google.com";
+}
+
 bool IsForwardBackLoad(ui::PageTransition transition) {
   return transition & ui::PAGE_TRANSITION_FORWARD_BACK;
 }
@@ -166,18 +177,24 @@
     const page_load_metrics::mojom::PageLoadTiming& timing) {
   if (!IsServiceWorkerControlled()) {
     if (!page_load_metrics::WasStartedInForegroundOptionalEventInForeground(
-            timing.paint_timing->first_contentful_paint, GetDelegate()) ||
-        !page_load_metrics::IsGoogleSearchResultUrl(GetDelegate().GetUrl())) {
+            timing.paint_timing->first_contentful_paint, GetDelegate())) {
       return;
     }
-    PAGE_LOAD_HISTOGRAM(
-        internal::kHistogramNoServiceWorkerFirstContentfulPaintSearch,
-        timing.paint_timing->first_contentful_paint.value());
-    PAGE_LOAD_HISTOGRAM(
-        internal::
-            kHistogramNoServiceWorkerParseStartToFirstContentfulPaintSearch,
-        timing.paint_timing->first_contentful_paint.value() -
-            timing.parse_timing->parse_start.value());
+
+    if (page_load_metrics::IsGoogleSearchResultUrl(GetDelegate().GetUrl())) {
+      PAGE_LOAD_HISTOGRAM(
+          internal::kHistogramNoServiceWorkerFirstContentfulPaintSearch,
+          timing.paint_timing->first_contentful_paint.value());
+      PAGE_LOAD_HISTOGRAM(
+          internal::
+              kHistogramNoServiceWorkerParseStartToFirstContentfulPaintSearch,
+          timing.paint_timing->first_contentful_paint.value() -
+              timing.parse_timing->parse_start.value());
+    } else if (IsDocsSite(GetDelegate().GetUrl())) {
+      PAGE_LOAD_HISTOGRAM(
+          internal::kHistogramNoServiceWorkerFirstContentfulPaintDocs,
+          timing.paint_timing->first_contentful_paint.value());
+    }
     return;
   }
   if (!page_load_metrics::WasStartedInForegroundOptionalEventInForeground(
@@ -223,6 +240,10 @@
         internal::kHistogramServiceWorkerParseStartToFirstContentfulPaintSearch,
         timing.paint_timing->first_contentful_paint.value() -
             timing.parse_timing->parse_start.value());
+  } else if (IsDocsSite(GetDelegate().GetUrl())) {
+    PAGE_LOAD_HISTOGRAM(
+        internal::kHistogramServiceWorkerFirstContentfulPaintDocs,
+        timing.paint_timing->first_contentful_paint.value());
   }
 }
 
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h
index 8f38e39..a892dc89 100644
--- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h
@@ -58,6 +58,9 @@
 extern const char kHistogramNoServiceWorkerDomContentLoadedSearch[];
 extern const char kHistogramNoServiceWorkerLoadSearch[];
 
+extern const char kHistogramServiceWorkerFirstContentfulPaintDocs[];
+extern const char kHistogramNoServiceWorkerFirstContentfulPaintDocs[];
+
 }  // namespace internal
 
 class ServiceWorkerPageLoadMetricsObserver
diff --git a/chrome/browser/password_manager/save_password_infobar_delegate_android_unittest.cc b/chrome/browser/password_manager/save_password_infobar_delegate_android_unittest.cc
index 6f4bdd720..f4775f33 100644
--- a/chrome/browser/password_manager/save_password_infobar_delegate_android_unittest.cc
+++ b/chrome/browser/password_manager/save_password_infobar_delegate_android_unittest.cc
@@ -154,7 +154,7 @@
   auto manager = std::make_unique<MockPasswordFormManager>(
       &client_, driver_.AsWeakPtr(), observed_form_, &fetcher_,
       metrics_recorder);
-  manager->ProvisionallySave(observed_form_, &driver_);
+  manager->ProvisionallySave(observed_form_, &driver_, nullptr);
   return manager;
 }
 
diff --git a/chrome/browser/password_manager/update_password_infobar_delegate_android_unittest.cc b/chrome/browser/password_manager/update_password_infobar_delegate_android_unittest.cc
index 546557b..49aa65c 100644
--- a/chrome/browser/password_manager/update_password_infobar_delegate_android_unittest.cc
+++ b/chrome/browser/password_manager/update_password_infobar_delegate_android_unittest.cc
@@ -108,7 +108,7 @@
       &client_, driver_.AsWeakPtr(), observed_form_, &fetcher_,
       std::make_unique<password_manager::StubFormSaver>(),
       nullptr /* metrics_recorder */);
-  manager->ProvisionallySave(observed_form_, &driver_);
+  manager->ProvisionallySave(observed_form_, &driver_, nullptr);
   return manager;
 }
 
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index c8838494..37f5826 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -1225,7 +1225,8 @@
       SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED,
       SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED));
   handlers->AddHandler(
-      std::make_unique<WebUsbAllowDevicesForUrlsPolicyHandler>(chrome_schema));
+      WebUsbAllowDevicesForUrlsPolicyHandler::CreateForUserPolicy(
+          chrome_schema));
 
 // On most platforms, there is a legacy policy
 // kUnsafelyTreatInsecureOriginAsSecure which has been replaced by
@@ -1558,6 +1559,9 @@
       SCHEMA_ALLOW_UNKNOWN,
       SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED,
       SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED));
+  handlers->AddHandler(
+      WebUsbAllowDevicesForUrlsPolicyHandler::CreateForDevicePolicy(
+          chrome_schema));
 #endif  // defined(OS_CHROMEOS)
 
 #if BUILDFLAG(ENABLE_PLUGINS)
diff --git a/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history.py b/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history.py
index a698818..2a22c622 100644
--- a/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history.py
+++ b/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history.py
@@ -12,7 +12,7 @@
 class AllowDeletingBrowserHistory(ChromeEnterpriseTestCase):
   """Test the AllowDeletingBrowserHistory policy:
 
-    https://www.chromium.org/administrators/policy-list-3#AllowDeletingBrowserHistory.
+    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=AllowDeletingBrowserHistory.
     """
 
   @before_all
diff --git a/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing.py b/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing.py
index 010340afe..ea4a36c 100644
--- a/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing.py
+++ b/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing.py
@@ -11,7 +11,7 @@
 class SafeBrowsingEnabledTest(ChromeEnterpriseTestCase):
   """Test the SafeBrowsingEnabled policy.
 
-  See https://www.chromium.org/administrators/policy-list-3#SafeBrowsingEnabled"""
+  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=SafeBrowsingEnabled"""
 
   @before_all
   def setup(self):
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 0a7a5a7..08e1422a 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -4536,7 +4536,7 @@
         nullptr);
     auto urls = std::make_unique<base::Value>(base::Value::Type::LIST);
     for (const auto* url_string : kRestoredURLs)
-      urls->GetList().emplace_back(url_string);
+      urls->Append(url_string);
     policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                  POLICY_SOURCE_CLOUD, std::move(urls), nullptr);
     provider_.UpdateChromePolicy(policies);
@@ -6548,7 +6548,7 @@
             GetAppLockScreenStatus(app->id()));
 
   auto policy = std::make_unique<base::ListValue>();
-  policy->GetList().emplace_back(base::Value(kTestAppId));
+  policy->Append(base::Value(kTestAppId));
   SetPolicyValue(std::move(policy));
 
   EXPECT_EQ(chromeos::NoteTakingLockScreenSupport::kSupported,
@@ -6850,17 +6850,17 @@
   device_value.SetKey("product_id", base::Value(0));
 
   base::Value devices_value(base::Value::Type::LIST);
-  devices_value.GetList().push_back(std::move(device_value));
+  devices_value.Append(std::move(device_value));
 
   base::Value urls_value(base::Value::Type::LIST);
-  urls_value.GetList().emplace_back(base::Value("https://foo.com"));
+  urls_value.Append(base::Value("https://foo.com"));
 
   base::Value entry(base::Value::Type::DICTIONARY);
   entry.SetKey("devices", std::move(devices_value));
   entry.SetKey("urls", std::move(urls_value));
 
   auto policy_value = std::make_unique<base::Value>(base::Value::Type::LIST);
-  policy_value->GetList().push_back(std::move(entry));
+  policy_value->Append(std::move(entry));
 
   SetPolicy(&policies, key::kWebUsbAllowDevicesForUrls,
             std::move(policy_value));
@@ -6975,7 +6975,7 @@
     item.SetKey("default_launch_container", std::move(launch_container));
 
     base::Value list(base::Value::Type::LIST);
-    list.GetList().push_back(std::move(item));
+    list.Append(std::move(item));
 
     PolicyMap policies;
     SetPolicy(&policies, key::kWebAppInstallForceList,
diff --git a/chrome/browser/policy/policy_conversions.cc b/chrome/browser/policy/policy_conversions.cc
index 0a34214..7489aa730 100644
--- a/chrome/browser/policy/policy_conversions.cc
+++ b/chrome/browser/policy/policy_conversions.cc
@@ -220,7 +220,7 @@
     extension_policies_data.SetKey("name", Value(extension->name()));
     extension_policies_data.SetKey("id", Value(extension->id()));
     extension_policies_data.SetKey("policies", std::move(extension_policies));
-    policies.GetList().push_back(std::move(extension_policies_data));
+    policies.Append(std::move(extension_policies_data));
   }
 #endif
   return policies;
@@ -297,7 +297,7 @@
     current_account_policies_data.SetKey("name", Value(user_id));
     current_account_policies_data.SetKey("policies",
                                          std::move(current_account_policies));
-    policies.GetList().push_back(std::move(current_account_policies_data));
+    policies.Append(std::move(current_account_policies_data));
   }
 
   // Reset |user_policies_enabled_| setup.
@@ -365,9 +365,9 @@
   Value result(Value::Type::LIST);
   for (const auto& element : value_copy.GetList()) {
     if (element.is_dict()) {
-      result.GetList().emplace_back(Value(ConvertValueToJSON(element)));
+      result.Append(Value(ConvertValueToJSON(element)));
     } else {
-      result.GetList().push_back(element.Clone());
+      result.Append(element.Clone());
     }
   }
   return result;
@@ -452,7 +452,7 @@
     for (const auto& conflict : policy.conflicts) {
       base::Value conflicted_policy_value =
           GetPolicyValue(policy_name, conflict, errors, known_policy_schemas);
-      conflict_values.GetList().push_back(std::move(conflicted_policy_value));
+      conflict_values.Append(std::move(conflicted_policy_value));
     }
 
     value.SetKey("conflicts", std::move(conflict_values));
@@ -569,7 +569,7 @@
   Value all_policies(Value::Type::LIST);
 
   if (profile()) {
-    all_policies.GetList().push_back(GetChromePolicies());
+    all_policies.Append(GetChromePolicies());
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     Value extension_policies = GetExtensionsPolicies();
@@ -589,7 +589,7 @@
 
   Value identity_fields = GetIdentityFields();
   if (!identity_fields.is_none())
-    all_policies.GetList().push_back(std::move(identity_fields));
+    all_policies.Append(std::move(identity_fields));
 #endif  // defined(OS_CHROMEOS)
 
   return all_policies;
diff --git a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
index 2bc531f..39fc46ab 100644
--- a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
+++ b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
@@ -17,6 +17,7 @@
 #include "components/policy/core/browser/policy_error_map.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/policy_constants.h"
+#include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_value_map.h"
 #include "url/gurl.h"
 
@@ -38,12 +39,42 @@
 
 }  // namespace
 
+// static
+std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler>
+WebUsbAllowDevicesForUrlsPolicyHandler::CreateForUserPolicy(
+    const Schema& chrome_schema) {
+  return std::make_unique<WebUsbAllowDevicesForUrlsPolicyHandler>(
+      key::kWebUsbAllowDevicesForUrls, prefs::kManagedWebUsbAllowDevicesForUrls,
+      chrome_schema);
+}
+
+#if defined(OS_CHROMEOS)
+// static
+std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler>
+WebUsbAllowDevicesForUrlsPolicyHandler::CreateForDevicePolicy(
+    const Schema& chrome_schema) {
+  return std::make_unique<WebUsbAllowDevicesForUrlsPolicyHandler>(
+      key::kDeviceLoginScreenWebUsbAllowDevicesForUrls,
+      prefs::kDeviceLoginScreenWebUsbAllowDevicesForUrls, chrome_schema);
+}
+
+// static
+void WebUsbAllowDevicesForUrlsPolicyHandler::RegisterPrefs(
+    PrefRegistrySimple* registry) {
+  registry->RegisterListPref(
+      prefs::kDeviceLoginScreenWebUsbAllowDevicesForUrls);
+}
+#endif  // defined(OS_CHROMEOS)
+
 WebUsbAllowDevicesForUrlsPolicyHandler::WebUsbAllowDevicesForUrlsPolicyHandler(
-    Schema schema)
+    const char* policy_name,
+    const char* pref_name,
+    const Schema& chrome_schema)
     : SchemaValidatingPolicyHandler(
-          key::kWebUsbAllowDevicesForUrls,
-          schema.GetKnownProperty(key::kWebUsbAllowDevicesForUrls),
-          SchemaOnErrorStrategy::SCHEMA_ALLOW_UNKNOWN) {}
+          policy_name,
+          chrome_schema.GetKnownProperty(policy_name),
+          SchemaOnErrorStrategy::SCHEMA_ALLOW_UNKNOWN),
+      pref_name_(pref_name) {}
 
 WebUsbAllowDevicesForUrlsPolicyHandler::
     ~WebUsbAllowDevicesForUrlsPolicyHandler() {}
@@ -90,7 +121,7 @@
           device.FindKeyOfType(kProductIdKey, base::Value::Type::INTEGER);
       if (product_id_value) {
         // If a |product_id| is specified, then a |vendor_id| must also be
-        // specified. Otherwise, the device policy is invalid.
+        // specified. Otherwise, the policy is invalid.
         if (vendor_id_value) {
           const int product_id = product_id_value->GetInt();
           if (product_id > 0xFFFF || product_id < 0) {
@@ -181,7 +212,7 @@
   if (!value || !value->is_list())
     return;
 
-  prefs->SetValue(prefs::kManagedWebUsbAllowDevicesForUrls,
+  prefs->SetValue(pref_name_,
                   base::Value::FromUniquePtrValue(std::move(value)));
 }
 
diff --git a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h
index 9580c4c..a4a13d2 100644
--- a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h
+++ b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h
@@ -5,9 +5,12 @@
 #ifndef CHROME_BROWSER_POLICY_WEBUSB_ALLOW_DEVICES_FOR_URLS_POLICY_HANDLER_H_
 #define CHROME_BROWSER_POLICY_WEBUSB_ALLOW_DEVICES_FOR_URLS_POLICY_HANDLER_H_
 
+#include <memory>
+
 #include "base/macros.h"
 #include "components/policy/core/browser/configuration_policy_handler.h"
 
+class PrefRegistrySimple;
 class PrefValueMap;
 
 namespace policy {
@@ -18,7 +21,19 @@
 class WebUsbAllowDevicesForUrlsPolicyHandler
     : public SchemaValidatingPolicyHandler {
  public:
-  explicit WebUsbAllowDevicesForUrlsPolicyHandler(Schema schema);
+  static std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler>
+  CreateForUserPolicy(const Schema& chrome_schema);
+
+#if defined(OS_CHROMEOS)
+  static std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler>
+  CreateForDevicePolicy(const Schema& chrome_schema);
+
+  static void RegisterPrefs(PrefRegistrySimple* registry);
+#endif  // defined(OS_CHROMEOS)
+
+  WebUsbAllowDevicesForUrlsPolicyHandler(const char* policy_name,
+                                         const char* pref_name,
+                                         const Schema& chrome_schema);
   ~WebUsbAllowDevicesForUrlsPolicyHandler() override;
 
   // ConfigurationPolicyHandler implementation:
@@ -28,6 +43,9 @@
                            PrefValueMap* prefs) override;
 
  private:
+  // The name of the pref to apply the policy to.
+  const char* pref_name_;
+
   DISALLOW_COPY_AND_ASSIGN(WebUsbAllowDevicesForUrlsPolicyHandler);
 };
 
diff --git a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc
index 1c0c1b2..138f1ca 100644
--- a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc
+++ b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/json/json_reader.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/common/pref_names.h"
 #include "components/content_settings/core/common/pref_names.h"
 #include "components/policy/core/browser/configuration_policy_pref_store.h"
 #include "components/policy/core/browser/configuration_policy_pref_store_test.h"
@@ -18,11 +19,16 @@
 #include "components/policy/core/common/policy_types.h"
 #include "components/policy/core/common/schema.h"
 #include "components/policy/policy_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace policy {
 
 namespace {
 
+// For ChromeOS this test is parameterized to test user and device policy. For
+// other operating systems, this test just tests the user policy.
+enum class PolicyType { kUser, kDevice };
+
 constexpr char kDevicesKey[] = "devices";
 constexpr char kUrlsKey[] = "urls";
 constexpr char kVendorIdKey[] = "vendor_id";
@@ -203,6 +209,35 @@
       }
     ])";
 
+std::string GetPolicyName(PolicyType policy_type) {
+#if defined(OS_CHROMEOS)
+  if (policy_type == PolicyType::kDevice)
+    return key::kDeviceLoginScreenWebUsbAllowDevicesForUrls;
+#endif  // defined(OS_CHROMEOS)
+  return key::kWebUsbAllowDevicesForUrls;
+}
+
+std::string GetPrefName(PolicyType policy_type) {
+#if defined(OS_CHROMEOS)
+  if (policy_type == PolicyType::kDevice)
+    return prefs::kDeviceLoginScreenWebUsbAllowDevicesForUrls;
+#endif  // defined(OS_CHROMEOS)
+  return prefs::kManagedWebUsbAllowDevicesForUrls;
+}
+
+std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler> CreateHandler(
+    PolicyType policy_type,
+    const Schema& chrome_schema) {
+#if defined(OS_CHROMEOS)
+  if (policy_type == PolicyType::kDevice) {
+    return WebUsbAllowDevicesForUrlsPolicyHandler::CreateForDevicePolicy(
+        chrome_schema);
+  }
+#endif  // defined(OS_CHROMEOS)
+  return WebUsbAllowDevicesForUrlsPolicyHandler::CreateForUserPolicy(
+      chrome_schema);
+}
+
 std::unique_ptr<base::Value> ReadJson(base::StringPiece json) {
   base::Optional<base::Value> value = base::JSONReader::Read(json);
   EXPECT_TRUE(value);
@@ -212,44 +247,54 @@
 }  // namespace
 
 class WebUsbAllowDevicesForUrlsPolicyHandlerTest
-    : public ConfigurationPolicyPrefStoreTest {
+    : public ConfigurationPolicyPrefStoreTest,
+      public testing::WithParamInterface<PolicyType> {
  public:
+  WebUsbAllowDevicesForUrlsPolicyHandlerTest()
+      : policy_name_(GetPolicyName(GetParam())),
+        pref_name_(GetPrefName(GetParam())) {}
+
   WebUsbAllowDevicesForUrlsPolicyHandler* handler() { return handler_; }
 
+ protected:
+  const std::string policy_name_;
+  const std::string pref_name_;
+
  private:
   void SetUp() override {
     Schema chrome_schema = Schema::Wrap(GetChromeSchemaData());
-    auto handler =
-        std::make_unique<WebUsbAllowDevicesForUrlsPolicyHandler>(chrome_schema);
+    auto handler = CreateHandler(GetParam(), chrome_schema);
     handler_ = handler.get();
     handler_list_.AddHandler(std::move(handler));
   }
 
   WebUsbAllowDevicesForUrlsPolicyHandler* handler_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebUsbAllowDevicesForUrlsPolicyHandlerTest);
 };
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest, CheckPolicySettings) {
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest, CheckPolicySettings) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kValidPolicy), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD, ReadJson(kValidPolicy),
+             nullptr);
   ASSERT_TRUE(errors.empty());
   EXPECT_TRUE(handler()->CheckPolicySettings(policy, &errors));
   EXPECT_TRUE(errors.empty());
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithInvalidTopLevelEntry) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyInvalidTopLevelEntry), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyInvalidTopLevelEntry), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -258,18 +303,18 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[1]\": Missing or invalid required "
       "property: devices");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithMissingDevicesProperty) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyMissingDevicesProperty), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyMissingDevicesProperty), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -278,18 +323,18 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0]\": Missing or invalid required "
       "property: devices");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithMissingUrlsProperty) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyMissingUrlsProperty), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyMissingUrlsProperty), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -298,18 +343,18 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0]\": Missing or invalid required "
       "property: urls");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsUnknownProperty) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyUnknownProperty), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyUnknownProperty), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_TRUE(handler()->CheckPolicySettings(policy, &errors));
@@ -318,38 +363,38 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0].devices.items[0]\": Unknown "
       "property: serialNumber");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithMismatchedVendorIdType) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyMismatchedVendorIdType), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyMismatchedVendorIdType), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
   EXPECT_EQ(1ul, errors.size());
 
   const base::string16 kExpected = base::ASCIIToUTF16(
-      "Schema validation error at \"items[0].devices.items[0]\": The vendor_id "
-      "must be an unsigned short integer");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+      "Schema validation error at \"items[0].devices.items[0]\": The "
+      "vendor_id must be an unsigned short integer");
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithMismatchedProductIdType) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyMismatchedProductIdType), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyMismatchedProductIdType), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -358,18 +403,18 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0].devices.items[0]\": The "
       "product_id must be an unsigned short integer");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithProductIdWithoutVendorId) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyProductIdWithoutVendorId), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyProductIdWithoutVendorId), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -378,18 +423,18 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0].devices.items[0]\": A vendor_id "
       "must also be specified");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithInvalidRequestingUrlEntry) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyInvalidRequestingUrl), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyInvalidRequestingUrl), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -398,18 +443,18 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0].urls.items[0]\": The urls item "
       "must contain valid URLs");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithInvalidEmbeddingUrlEntry) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyInvalidEmbeddingUrl), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyInvalidEmbeddingUrl), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -418,18 +463,18 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0].urls.items[0]\": The urls item "
       "must contain valid URLs");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithInvalidUrlsEntry) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyInvalidUrlsEntry), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyInvalidUrlsEntry), nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -438,18 +483,18 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0].urls.items[0]\": Each urls "
       "string entry must contain between 1 to 2 URLs");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        CheckPolicySettingsWithNoUrls) {
   PolicyMap policy;
   PolicyErrorMap errors;
 
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(InvalidPolicyNoUrls), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD, ReadJson(InvalidPolicyNoUrls),
+             nullptr);
 
   ASSERT_TRUE(errors.empty());
   EXPECT_FALSE(handler()->CheckPolicySettings(policy, &errors));
@@ -458,23 +503,21 @@
   const base::string16 kExpected = base::ASCIIToUTF16(
       "Schema validation error at \"items[0].urls.items[0]\": Each urls "
       "string entry must contain between 1 to 2 URLs");
-  EXPECT_EQ(kExpected, errors.GetErrors(key::kWebUsbAllowDevicesForUrls));
+  EXPECT_EQ(kExpected, errors.GetErrors(policy_name_));
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest, ApplyPolicySettings) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest, ApplyPolicySettings) {
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kValidPolicy), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD, ReadJson(kValidPolicy),
+             nullptr);
   UpdateProviderPolicy(policy);
 
   const base::Value* pref_value = nullptr;
-  EXPECT_TRUE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_TRUE(store_->GetValue(pref_name_, &pref_value));
   ASSERT_TRUE(pref_value);
   ASSERT_TRUE(pref_value->is_list());
 
@@ -539,72 +582,64 @@
   EXPECT_EQ("https://chromium.org,", second_urls_list[0].GetString());
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsWithInvalidTopLevelEntry) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyInvalidTopLevelEntry), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyInvalidTopLevelEntry), nullptr);
   UpdateProviderPolicy(policy);
 
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsWithMissingDevicesProperty) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyMissingDevicesProperty), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyMissingDevicesProperty), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsWithMissingUrlsProperty) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyMissingUrlsProperty), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyMissingUrlsProperty), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsWithUnknownProperty) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyUnknownProperty), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyUnknownProperty), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_TRUE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_TRUE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_TRUE(pref_value);
 
   std::unique_ptr<base::Value> expected_pref_value =
@@ -612,122 +647,119 @@
   EXPECT_EQ(*expected_pref_value, *pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsWithMismatchedVendorIdType) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyMismatchedVendorIdType), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyMismatchedVendorIdType), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsWithMismatchedProductIdType) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyMismatchedProductIdType), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyMismatchedProductIdType), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsProductIdWithoutVendorId) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyProductIdWithoutVendorId), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyProductIdWithoutVendorId), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsInvalidRequestingUrl) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyInvalidRequestingUrl), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyInvalidRequestingUrl), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsInvalidEmbeddingUrl) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyInvalidEmbeddingUrl), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyInvalidEmbeddingUrl), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest,
        ApplyPolicySettingsInvalidUrlsEntry) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(kInvalidPolicyInvalidUrlsEntry), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD,
+             ReadJson(kInvalidPolicyInvalidUrlsEntry), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
-TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest, ApplyPolicySettingsNoUrls) {
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
+TEST_P(WebUsbAllowDevicesForUrlsPolicyHandlerTest, ApplyPolicySettingsNoUrls) {
+  EXPECT_FALSE(store_->GetValue(pref_name_, nullptr));
 
   PolicyMap policy;
-  policy.Set(
-      key::kWebUsbAllowDevicesForUrls, PolicyLevel::POLICY_LEVEL_MANDATORY,
-      PolicyScope::POLICY_SCOPE_MACHINE, PolicySource::POLICY_SOURCE_CLOUD,
-      ReadJson(InvalidPolicyNoUrls), nullptr);
+  policy.Set(policy_name_, PolicyLevel::POLICY_LEVEL_MANDATORY,
+             PolicyScope::POLICY_SCOPE_MACHINE,
+             PolicySource::POLICY_SOURCE_CLOUD, ReadJson(InvalidPolicyNoUrls),
+             nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  EXPECT_FALSE(
-      store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, &pref_value));
+  EXPECT_FALSE(store_->GetValue(pref_name_, &pref_value));
   EXPECT_FALSE(pref_value);
 }
 
+// For ChromeOS this test is parameterized to test user and device policy. For
+// other operating systems, this test just tests the user policy.
+INSTANTIATE_TEST_SUITE_P(,
+                         WebUsbAllowDevicesForUrlsPolicyHandlerTest,
+#if defined(OS_CHROMEOS)
+                         testing::Values(PolicyType::kUser, PolicyType::kDevice)
+#else
+                         testing::Values(PolicyType::kUser)
+#endif
+);
+
 }  // namespace policy
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 45e09c1..ce7a864 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -45,6 +45,7 @@
 #include "chrome/browser/notifications/platform_notification_service_impl.h"
 #include "chrome/browser/pepper_flash_settings_manager.h"
 #include "chrome/browser/policy/developer_tools_policy_handler.h"
+#include "chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h"
 #include "chrome/browser/prefs/chrome_pref_service_factory.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/prefs/origin_trial_prefs.h"
@@ -700,6 +701,7 @@
   policy::DMTokenStorage::RegisterPrefs(registry);
   policy::PolicyCertServiceFactory::RegisterPrefs(registry);
   policy::TPMAutoUpdateModePolicyHandler::RegisterPrefs(registry);
+  policy::WebUsbAllowDevicesForUrlsPolicyHandler::RegisterPrefs(registry);
   quirks::QuirksManager::RegisterPrefs(registry);
   UpgradeDetectorChromeos::RegisterPrefs(registry);
   syncer::PerUserTopicRegistrationManager::RegisterPrefs(registry);
diff --git a/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc b/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
index 35efb3dea..8defd79b 100644
--- a/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
+++ b/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
@@ -171,6 +171,7 @@
 
   redirect_info_ = net::RedirectInfo::ComputeRedirectInfo(
       modified_resource_request_.method, modified_resource_request_.url,
+      modified_resource_request_.request_initiator,
       modified_resource_request_.site_for_cookies,
       net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT,
       modified_resource_request_.referrer_policy,
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 56058d9..c193333 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -273,7 +273,7 @@
   return false;
 }
 
-network::mojom::NetworkContextPtr Profile::CreateNetworkContext(
+mojo::Remote<network::mojom::NetworkContext> Profile::CreateNetworkContext(
     bool in_memory,
     const base::FilePath& relative_partition_path) {
   return ProfileNetworkContextServiceFactory::GetForContext(this)
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index 6a7b2e1c..bb090879 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -19,6 +19,7 @@
 #include "components/domain_reliability/clear_mode.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/content_browser_client.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/network_service.mojom-forward.h"
 
 #if !defined(OS_ANDROID)
@@ -375,7 +376,7 @@
 
   // Creates NetworkContext for the specified isolated app (or for the profile
   // itself, if |relative_path| is empty).
-  virtual network::mojom::NetworkContextPtr CreateNetworkContext(
+  virtual mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       bool in_memory,
       const base::FilePath& relative_partition_path);
 
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 5fb5b84..72136e5 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -252,7 +252,7 @@
   // on shutdown. In case of a crash remaining files are removed on next start.
   ListPrefUpdate deleted_profiles(g_browser_process->local_state(),
                                   prefs::kProfilesDeleted);
-  deleted_profiles->GetList().push_back(CreateFilePathValue(path));
+  deleted_profiles->Append(CreateFilePathValue(path));
 }
 
 // Cancel a scheduling deletion, so ScheduleProfileDirectoryForDeletion can be
diff --git a/chrome/browser/profiling_host/profiling_process_host.cc b/chrome/browser/profiling_host/profiling_process_host.cc
index efc1e4f..2b0df49 100644
--- a/chrome/browser/profiling_host/profiling_process_host.cc
+++ b/chrome/browser/profiling_host/profiling_process_host.cc
@@ -77,7 +77,7 @@
   base::Value rule(base::Value::Type::DICTIONARY);
   rule.SetKey("rule", base::Value("MEMLOG"));
   rule.SetKey("trigger_name", base::Value(std::move(trigger_name)));
-  rules_list.GetList().push_back(std::move(rule));
+  rules_list.Append(std::move(rule));
 
   std::string sampling_mode = base::StringPrintf("SAMPLING_%u", sampling_rate);
 
diff --git a/chrome/browser/resources/bookmarks/README.md b/chrome/browser/resources/bookmarks/README.md
index c6c83b16..272a91d 100644
--- a/chrome/browser/resources/bookmarks/README.md
+++ b/chrome/browser/resources/bookmarks/README.md
@@ -23,11 +23,11 @@
   and between two different BMM instances from different Chrome profiles.
 * **Policy support**: Several policies are respected:
 
-  - [EditBookmarksEnabled](https://www.chromium.org/administrators/policy-list-3#EditBookmarksEnabled):
+  - [EditBookmarksEnabled](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=EditBookmarksEnabled):
     Prevents all editing operations
-  - [ManagedBookmarks](https://www.chromium.org/administrators/policy-list-3#ManagedBookmarks):
+  - [ManagedBookmarks](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ManagedBookmarks):
     Defines a folder of immutable bookmarks.
-  - [IncognitoModeAvailability](https://www.chromium.org/administrators/policy-list-3#IncognitoModeAvailability):
+  - [IncognitoModeAvailability](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=IncognitoModeAvailability):
     Disables/force-enables opening bookmarks in Incognito
 
 ## Data-flow model
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_loading.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_loading.html
index ee362e42..15c7ade 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_loading.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_loading.html
@@ -33,7 +33,7 @@
             disabled="[[buttonsDisabled]]">
           <div i18n-content="assistantOptinSkipButton"></div>
         </oobe-text-button>
-        <oobe-text-button id="retry-button" inverse android
+        <oobe-text-button id="retry-button" inverse
             on-tap="onRetryTap_" disabled="[[buttonsDisabled]]">
           <div i18n-content="assistantOptinRetryButton"></div>
         </oobe-text-button>
diff --git a/chrome/browser/resources/chromeos/login/oobe_buttons.html b/chrome/browser/resources/chromeos/login/oobe_buttons.html
index 20ef6b33..373a888 100644
--- a/chrome/browser/resources/chromeos/login/oobe_buttons.html
+++ b/chrome/browser/resources/chromeos/login/oobe_buttons.html
@@ -59,7 +59,7 @@
     <link rel="stylesheet" href="oobe_text_buttons.css">
     <cr-button id="textButton" on-tap="onClick_" disabled="[[disabled]]"
         inverse$="[[inverse]]" aria-label$="[[labelForAria]]"
-        border$="[[border]]" android$="[[android]]">
+        border$="[[border]]">
       <div id="container"
           class="flex layout horizontal center center-justified self-stretch">
         <slot></slot>
diff --git a/chrome/browser/resources/chromeos/login/oobe_buttons.js b/chrome/browser/resources/chromeos/login/oobe_buttons.js
index 57d018a..f1da4755 100644
--- a/chrome/browser/resources/chromeos/login/oobe_buttons.js
+++ b/chrome/browser/resources/chromeos/login/oobe_buttons.js
@@ -15,8 +15,6 @@
 
     border: Boolean,
 
-    android: {type: Boolean, value: false},
-
     /* Note that we are not using "aria-label" property here, because
      * we want to pass the label value but not actually declare it as an
      * ARIA property anywhere but the actual target element.
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog.css b/chrome/browser/resources/chromeos/login/oobe_dialog.css
index a0e4fc3..11ce8fed 100644
--- a/chrome/browser/resources/chromeos/login/oobe_dialog.css
+++ b/chrome/browser/resources/chromeos/login/oobe_dialog.css
@@ -77,18 +77,6 @@
   padding: unset;
 }
 
-#oobe-bottom[android] {
-  box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.14);
-}
-
-#oobe-bottom[android][hideShadow] {
-  box-shadow: unset;
-}
-
-#oobe-bottom[android] {
-  height: 60px;
-}
-
 #oobe-bottom ::slotted(*) {
   width: 100%;
 }
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog.html b/chrome/browser/resources/chromeos/login/oobe_dialog.html
index 6363c8f..c7cdfbf 100644
--- a/chrome/browser/resources/chromeos/login/oobe_dialog.html
+++ b/chrome/browser/resources/chromeos/login/oobe_dialog.html
@@ -58,7 +58,7 @@
     <link rel="stylesheet" href="oobe_dialog.css">
     <link rel="stylesheet" href="oobe_flex_layout.css">
     <style include="cr-shared-style"></style>
-    <div id="header-container" hidden="[[noHeader]]" android$="[[android]]">
+    <div id="header-container" hidden="[[noHeader]]">
       <div id="oobe-icon-div">
         <slot name="oobe-icon"></slot>
       </div>
@@ -77,7 +77,7 @@
       <slot name="footer"></slot>
     </div>
     <template is="dom-if" if="[[hasButtons]]">
-      <div id="oobe-bottom" hideShadow$="[[hideShadow]]" android$="[[android]]"
+      <div id="oobe-bottom" hideShadow$="[[hideShadow]]"
         no-buttons-padding$="[[noButtonsPadding]]"
           class="layout horizontal center">
         <slot name="bottom-buttons"></slot>
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog.js b/chrome/browser/resources/chromeos/login/oobe_dialog.js
index a139554..4702732d 100644
--- a/chrome/browser/resources/chromeos/login/oobe_dialog.js
+++ b/chrome/browser/resources/chromeos/login/oobe_dialog.js
@@ -55,11 +55,6 @@
       reflectToAttribute: true,
       observer: 'onfullScreenDialogChanged_',
     },
-
-    android: {
-      type: Boolean,
-      value: false,
-    },
   },
 
   focus: function() {
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog_host.css b/chrome/browser/resources/chromeos/login/oobe_dialog_host.css
index 5647c4b..4665668 100644
--- a/chrome/browser/resources/chromeos/login/oobe_dialog_host.css
+++ b/chrome/browser/resources/chromeos/login/oobe_dialog_host.css
@@ -22,8 +22,3 @@
   border-radius: 4px;
   box-shadow: 0 24px 24px rgba(0, 0, 0, .24), 0 0 24px rgba(0, 0, 0, .12);
 }
-
-:host([android]) {
-  min-height: 480px;
-  min-width: 576px;
-}
diff --git a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
index a9743344..78ac464 100644
--- a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
+++ b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
@@ -19,7 +19,7 @@
       <div slot="title">$i18n{aboutChangeChannel}</div>
       <div slot="body">
         <!-- TODO(dbeam): this can be policy-controlled. Show this in the UI.
-             https://www.chromium.org/administrators/policy-list-3#ChromeOsReleaseChannel
+             https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ChromeOsReleaseChannel
         -->
         <cr-radio-group on-selected-changed="onChannelSelectionChanged_">
           <cr-radio-button name="[[browserChannelEnum_.STABLE]]">
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
index 8c08f13..1509f61 100644
--- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
@@ -147,8 +147,8 @@
       }
       case Value::Type::LIST: {
         Value value(base::Value::Type::LIST);
-        value.GetList().emplace_back(22);
-        value.GetList().emplace_back(47);
+        value.Append(22);
+        value.Append(47);
         return value;
       }
       default:
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index 3eeccbed..764baf11 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -352,7 +352,7 @@
     dict.SetKey("collectionName", base::Value(collection.collection_name));
     dict.SetKey("previewImageUrl",
                 base::Value(collection.preview_image_url.spec()));
-    collections.GetList().push_back(std::move(dict));
+    collections.Append(std::move(dict));
   }
   return collections;
 }
@@ -369,12 +369,12 @@
     dict.SetKey("collectionId", base::Value(image.collection_id));
     base::Value attributions(base::Value::Type::LIST);
     for (const auto& attribution : image.attribution) {
-      attributions.GetList().push_back(base::Value(attribution));
+      attributions.Append(base::Value(attribution));
     }
     dict.SetKey("attributions", std::move(attributions));
     dict.SetKey("attributionActionUrl",
                 base::Value(image.attribution_action_url.spec()));
-    images.GetList().push_back(std::move(dict));
+    images.Append(std::move(dict));
   }
   return images;
 }
diff --git a/chrome/browser/search/search_suggest/search_suggest_service.cc b/chrome/browser/search/search_suggest/search_suggest_service.cc
index cb93ea92..54d3a06a 100644
--- a/chrome/browser/search/search_suggest/search_suggest_service.cc
+++ b/chrome/browser/search/search_suggest/search_suggest_service.cc
@@ -297,7 +297,7 @@
   base::Value* value = blocklist->FindKey(task_version_id);
   if (!value)
     value = blocklist->SetKey(task_version_id, base::ListValue());
-  value->GetList().emplace_back(base::Value(hash_string));
+  value->Append(base::Value(hash_string));
 
   search_suggest_data_ = base::nullopt;
   Refresh();
diff --git a/chrome/browser/site_isolation/site_isolation_policy_unittest.cc b/chrome/browser/site_isolation/site_isolation_policy_unittest.cc
index 3772365..7ecac8e 100644
--- a/chrome/browser/site_isolation/site_isolation_policy_unittest.cc
+++ b/chrome/browser/site_isolation/site_isolation_policy_unittest.cc
@@ -63,8 +63,8 @@
     ListPrefUpdate update(profile->GetPrefs(),
                           prefs::kUserTriggeredIsolatedOrigins);
     base::ListValue* list = update.Get();
-    list->GetList().emplace_back("http://foo.com");
-    list->GetList().emplace_back("https://bar.com");
+    list->Append("http://foo.com");
+    list->Append("https://bar.com");
   }
 
   // New SiteInstances for foo.com and bar.com shouldn't require a dedicated
@@ -141,7 +141,7 @@
     ListPrefUpdate update(profile->GetPrefs(),
                           prefs::kUserTriggeredIsolatedOrigins);
     base::ListValue* list = update.Get();
-    list->GetList().emplace_back("http://foo.com");
+    list->Append("http://foo.com");
   }
 
   // Applying saved isolated origins should have no effect, since site
diff --git a/chrome/browser/ssl/chrome_ssl_host_state_delegate.cc b/chrome/browser/ssl/chrome_ssl_host_state_delegate.cc
index 29ccbf2..9ac50ce6 100644
--- a/chrome/browser/ssl/chrome_ssl_host_state_delegate.cc
+++ b/chrome/browser/ssl/chrome_ssl_host_state_delegate.cc
@@ -122,7 +122,7 @@
     // (i.e. out of order). Save a new list composed of just this one error
     // instance.
     base::ListValue error_list;
-    error_list.GetList().push_back(base::Value(now));
+    error_list.Append(base::Value(now));
     pref_update->SetKey(net::ErrorToShortString(error), std::move(error_list));
   } else {
     // Only up to |threshold| values need to be stored. If the list already
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 5e4d0be..9307472 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -1884,7 +1884,7 @@
     std::unique_ptr<base::ListValue> policy_value =
         std::make_unique<base::ListValue>();
     for (const auto& value : list_values) {
-      policy_value->GetList().emplace_back(value);
+      policy_value->Append(value);
     }
     policy::PolicyMap policy_map;
     policy_map.Set(policy_name, policy::POLICY_LEVEL_MANDATORY,
@@ -2279,7 +2279,7 @@
   base::Value* filters = setting->SetKey("filters", base::ListValue());
   base::DictionaryValue filter = base::DictionaryValue();
   filter.SetString("ISSUER.CN", "pywebsocket");
-  filters->GetList().push_back(std::move(filter));
+  filters->Append(std::move(filter));
   HostContentSettingsMapFactory::GetForProfile(profile)
       ->SetWebsiteSettingDefaultScope(
           url, GURL(), CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
@@ -2381,7 +2381,7 @@
   std::unique_ptr<base::DictionaryValue> setting =
       std::make_unique<base::DictionaryValue>();
   base::Value* filters = setting->SetKey("filters", base::ListValue());
-  filters->GetList().push_back(base::DictionaryValue());
+  filters->Append(base::DictionaryValue());
   HostContentSettingsMapFactory::GetForProfile(profile)
       ->SetWebsiteSettingDefaultScope(
           https_url, GURL(), CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
@@ -2417,7 +2417,7 @@
   std::unique_ptr<base::DictionaryValue> setting =
       std::make_unique<base::DictionaryValue>();
   base::Value* filters = setting->SetKey("filters", base::ListValue());
-  filters->GetList().push_back(base::DictionaryValue());
+  filters->Append(base::DictionaryValue());
   HostContentSettingsMapFactory::GetForProfile(profile)
       ->SetWebsiteSettingDefaultScope(
           https_url, GURL(), CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
@@ -2480,7 +2480,7 @@
   std::unique_ptr<base::DictionaryValue> setting =
       std::make_unique<base::DictionaryValue>();
   base::Value* filters = setting->SetKey("filters", base::ListValue());
-  filters->GetList().push_back(base::DictionaryValue());
+  filters->Append(base::DictionaryValue());
   HostContentSettingsMapFactory::GetForProfile(profile)
       ->SetWebsiteSettingDefaultScope(
           https_url, GURL(), CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
diff --git a/chrome/browser/ssl/ssl_config_service_manager_pref_unittest.cc b/chrome/browser/ssl/ssl_config_service_manager_pref_unittest.cc
index 4ea334d9..9b9b453 100644
--- a/chrome/browser/ssl/ssl_config_service_manager_pref_unittest.cc
+++ b/chrome/browser/ssl/ssl_config_service_manager_pref_unittest.cc
@@ -247,15 +247,15 @@
 
   auto patterns = std::make_unique<base::ListValue>();
   // Patterns expected to be canonicalized.
-  patterns->GetList().emplace_back(base::Value("canon.example"));
-  patterns->GetList().emplace_back(base::Value(".NonCanon.example"));
-  patterns->GetList().emplace_back(base::Value("Non-Canon.example"));
-  patterns->GetList().emplace_back(base::Value("127.0.0.1"));
-  patterns->GetList().emplace_back(base::Value("2147614986"));
+  patterns->Append(base::Value("canon.example"));
+  patterns->Append(base::Value(".NonCanon.example"));
+  patterns->Append(base::Value("Non-Canon.example"));
+  patterns->Append(base::Value("127.0.0.1"));
+  patterns->Append(base::Value("2147614986"));
   // Patterns expected to be skipped.
-  patterns->GetList().emplace_back(base::Value("???"));
-  patterns->GetList().emplace_back(base::Value("example.com/"));
-  patterns->GetList().emplace_back(base::Value("xn--hellö.com"));
+  patterns->Append(base::Value("???"));
+  patterns->Append(base::Value("example.com/"));
+  patterns->Append(base::Value("xn--hellö.com"));
   local_state.SetUserPref(prefs::kH2ClientCertCoalescingHosts,
                           std::move(patterns));
 
diff --git a/chrome/browser/sync/test/integration/p2p_sync_refresher.cc b/chrome/browser/sync/test/integration/p2p_sync_refresher.cc
deleted file mode 100644
index ad89e83..0000000
--- a/chrome/browser/sync/test/integration/p2p_sync_refresher.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/sync/test/integration/p2p_sync_refresher.h"
-
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
-#include "chrome/browser/sync/test/integration/sync_test.h"
-#include "components/sync/driver/profile_sync_service.h"
-#include "components/sync/engine/cycle/sync_cycle_snapshot.h"
-#include "content/public/browser/notification_service.h"
-
-P2PSyncRefresher::P2PSyncRefresher(Profile* profile,
-                                   syncer::ProfileSyncService* sync_service)
-    : profile_(profile), sync_service_(sync_service) {
-  sync_service_->AddObserver(this);
-}
-
-P2PSyncRefresher::~P2PSyncRefresher() {
-  sync_service_->RemoveObserver(this);
-}
-
-void P2PSyncRefresher::OnSyncCycleCompleted(syncer::SyncService* sync) {
-  const syncer::SyncCycleSnapshot& snap =
-      sync_service_->GetLastCycleSnapshotForDebugging();
-  bool is_notifiable_commit =
-      (snap.model_neutral_state().num_successful_commits > 0);
-  if (is_notifiable_commit) {
-    syncer::ModelTypeSet model_types =
-        snap.model_neutral_state().commit_request_types;
-    SyncTest* test = sync_datatype_helper::test();
-    for (int i = 0; i < test->num_clients(); ++i) {
-      if (profile_ != test->GetProfile(i))
-        test->TriggerSyncForModelTypes(i, model_types);
-    }
-  }
-}
diff --git a/chrome/browser/sync/test/integration/p2p_sync_refresher.h b/chrome/browser/sync/test/integration/p2p_sync_refresher.h
deleted file mode 100644
index b925c6a..0000000
--- a/chrome/browser/sync/test/integration/p2p_sync_refresher.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_P2P_SYNC_REFRESHER_H_
-#define CHROME_BROWSER_SYNC_TEST_INTEGRATION_P2P_SYNC_REFRESHER_H_
-
-#include "base/macros.h"
-#include "components/sync/driver/sync_service_observer.h"
-
-class Profile;
-
-namespace syncer {
-class ProfileSyncService;
-}  // namespace syncer
-
-// This class observes ProfileSyncService events and emits refresh notifications
-// to other test profiles for any committed changes it observes.
-//
-// It register and unregisters in its constructor and destructor.  This is
-// intended to make it easy to manage with a scoped_ptr.
-class P2PSyncRefresher : public syncer::SyncServiceObserver {
- public:
-  P2PSyncRefresher(Profile* profile, syncer::ProfileSyncService* sync_service);
-  ~P2PSyncRefresher() override;
-
-  // Implementation of syncer::SyncServiceObserver
-  void OnSyncCycleCompleted(syncer::SyncService* sync) override;
-
- private:
-  Profile* const profile_;            // weak
-  syncer::ProfileSyncService* sync_service_;  // weak
-
-  DISALLOW_COPY_AND_ASSIGN(P2PSyncRefresher);
-};
-
-#endif  // CHROME_BROWSER_SYNC_TEST_INTEGRATION_P2P_SYNC_REFRESHER_H_
diff --git a/chrome/browser/sync/test/integration/single_client_themes_sync_test.cc b/chrome/browser/sync/test/integration/single_client_themes_sync_test.cc
index f2f1034..6c05e9d 100644
--- a/chrome/browser/sync/test/integration/single_client_themes_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_themes_sync_test.cc
@@ -54,12 +54,7 @@
   EXPECT_EQ(GetCustomTheme(0), GetThemeID(verifier()));
 }
 
-// TODO(sync): Fails on Chrome OS. See http://crbug.com/84575.
-#if defined(OS_CHROMEOS)
-IN_PROC_BROWSER_TEST_F(SingleClientThemesSyncTest, DISABLED_NativeTheme) {
-#else
 IN_PROC_BROWSER_TEST_F(SingleClientThemesSyncTest, NativeTheme) {
-#endif  // OS_CHROMEOS
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   SetCustomTheme(GetProfile(0));
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index b77e899..46563311 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -29,7 +29,6 @@
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/browser/sync/test/integration/p2p_sync_refresher.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
@@ -568,7 +567,6 @@
   profiles_.resize(num_clients_);
   profile_delegates_.resize(num_clients_ + 1);  // + 1 for the verifier.
   clients_.resize(num_clients_);
-  sync_refreshers_.resize(num_clients_);
   fake_server_invalidation_observers_.resize(num_clients_);
 
   if (create_gaia_account_at_runtime_) {
@@ -864,20 +862,7 @@
     }
   }
 
-  // SyncRefresher is used instead of invalidations to notify other profiles to
-  // do a sync refresh on committed data sets. This is only needed when running
-  // tests against external live server, otherwise invalidation service is used.
-  // With external live servers, the profiles commit data on first sync cycle
-  // automatically after signing in. To avoid misleading sync commit
-  // notifications at start up, we start the SyncRefresher observers post
-  // client set up.
   if (UsingExternalServers()) {
-    for (int i = 0; i < num_clients_; ++i) {
-      DCHECK(!sync_refreshers_[i]);
-      sync_refreshers_[i] = std::make_unique<P2PSyncRefresher>(
-          GetProfile(i), clients_[i]->service());
-    }
-
     // OneClickSigninSyncStarter observer is created with a real user sign in.
     // It is deleted on certain conditions which are not satisfied by our tests,
     // and this causes the SigninTracker observer to stay hanging at shutdown.
@@ -923,7 +908,6 @@
   }
 
   // Delete things that unsubscribe in destructor before their targets are gone.
-  sync_refreshers_.clear();
   configuration_refresher_.reset();
 }
 
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h
index 79b2ad6..d6f4e22 100644
--- a/chrome/browser/sync/test/integration/sync_test.h
+++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -49,7 +49,6 @@
 #define E2E_ENABLED(test_name) MACRO_CONCAT(test_name, E2ETest)
 
 class ProfileSyncServiceHarness;
-class P2PSyncRefresher;
 
 namespace arc {
 class SyncArcPackageHelper;
@@ -465,10 +464,6 @@
   // Mapping from client indexes to decryption passphrases to use for them.
   std::map<int, std::string> client_decryption_passphrases_;
 
-  // A set of objects to listen for commit activity and broadcast refresh
-  // notifications of this activity to its peer sync clients.
-  std::vector<std::unique_ptr<P2PSyncRefresher>> sync_refreshers_;
-
   // Owns the FakeServerInvalidationSender for each profile.
   std::vector<std::unique_ptr<fake_server::FakeServerInvalidationSender>>
       fake_server_invalidation_observers_;
diff --git a/chrome/browser/sync_file_system/drive_backend/callback_helper_unittest.cc b/chrome/browser/sync_file_system/drive_backend/callback_helper_unittest.cc
index 26dd0e4..17865a6 100644
--- a/chrome/browser/sync_file_system/drive_backend/callback_helper_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/callback_helper_unittest.cc
@@ -43,7 +43,7 @@
 }  // namespace
 
 TEST(DriveBackendCallbackHelperTest, BasicTest) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
 
   bool called = false;
   RelayCallbackToCurrentThread(
@@ -63,7 +63,7 @@
 }
 
 TEST(DriveBackendCallbackHelperTest, RunOnOtherThreadTest) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   base::Thread thread("WorkerThread");
   thread.Start();
 
@@ -91,7 +91,7 @@
 }
 
 TEST(DriveBackendCallbackHelperTest, PassNullFunctionTest) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   base::Closure closure = RelayCallbackToCurrentThread(
       FROM_HERE,
       base::Closure());
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
index 0465696..e7de044 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
@@ -625,7 +625,7 @@
 
  private:
   base::ScopedTempDir database_dir_;
-  base::test::TaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   std::unique_ptr<leveldb::Env> in_memory_env_;
   std::unique_ptr<MetadataDatabase> metadata_database_;
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_task_manager_unittest.cc b/chrome/browser/sync_file_system/drive_backend/sync_task_manager_unittest.cc
index efcb26c0..4b99a3ce 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_task_manager_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_task_manager_unittest.cc
@@ -287,7 +287,7 @@
 }  // namespace
 
 TEST(SyncTaskManagerTest, ScheduleTask) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   TaskManagerClient client(0 /* maximum_background_task */);
   int callback_count = 0;
   SyncStatusCode callback_status = SYNC_STATUS_OK;
@@ -307,7 +307,7 @@
 }
 
 TEST(SyncTaskManagerTest, ScheduleTwoTasks) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   TaskManagerClient client(0 /* maximum_background_task */);
   int callback_count = 0;
   SyncStatusCode callback_status = SYNC_STATUS_OK;
@@ -330,7 +330,7 @@
 }
 
 TEST(SyncTaskManagerTest, ScheduleIdleTask) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   TaskManagerClient client(0 /* maximum_background_task */);
 
   client.ScheduleTaskIfIdle(kStatus1);
@@ -344,7 +344,7 @@
 }
 
 TEST(SyncTaskManagerTest, ScheduleIdleTaskWhileNotIdle) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   TaskManagerClient client(0 /* maximum_background_task */);
   int callback_count = 0;
   SyncStatusCode callback_status = SYNC_STATUS_OK;
@@ -366,7 +366,7 @@
 }
 
 TEST(SyncTaskManagerTest, ScheduleAndCancelSyncTask) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
 
   int callback_count = 0;
   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
@@ -395,7 +395,7 @@
 }
 
 TEST(SyncTaskManagerTest, ScheduleTaskAtPriority) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                                0 /* maximum_background_task */,
                                base::ThreadTaskRunnerHandle::Get());
@@ -456,7 +456,7 @@
 }
 
 TEST(SyncTaskManagerTest, BackgroundTask_Sequential) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                                10 /* maximum_background_task */,
                                base::ThreadTaskRunnerHandle::Get());
@@ -488,7 +488,7 @@
 }
 
 TEST(SyncTaskManagerTest, BackgroundTask_Parallel) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                                10 /* maximum_background_task */,
                                base::ThreadTaskRunnerHandle::Get());
@@ -520,7 +520,7 @@
 }
 
 TEST(SyncTaskManagerTest, BackgroundTask_Throttled) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                                2 /* maximum_background_task */,
                                base::ThreadTaskRunnerHandle::Get());
@@ -552,7 +552,7 @@
 }
 
 TEST(SyncTaskManagerTest, UpdateTaskBlocker) {
-  base::test::TaskEnvironment task_environment;
+  base::test::SingleThreadTaskEnvironment task_environment;
   SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                                10 /* maximum_background_task */,
                                base::ThreadTaskRunnerHandle::Get());
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.cc
index 96233c5b..890f833a 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.cc
@@ -244,7 +244,7 @@
                                   const std::string& model_identifier,
                                   OnConfigLoadedCallback callback) {
   DCHECK(connector_);
-  GetJsonParser().Parse(
+  GetJsonParser()->Parse(
       json_string,
       base::BindOnce(&JsonConfigConverter::OnJsonParsed, base::Unretained(this),
                      std::move(callback), model_identifier));
@@ -267,16 +267,16 @@
   }
 }
 
-data_decoder::mojom::JsonParser& JsonConfigConverter::GetJsonParser() {
+data_decoder::mojom::JsonParser* JsonConfigConverter::GetJsonParser() {
   if (!json_parser_) {
-    connector_->BindInterface(data_decoder::mojom::kServiceName,
-                              mojo::MakeRequest(&json_parser_));
-    json_parser_.set_connection_error_handler(base::BindOnce(
+    connector_->Connect(data_decoder::mojom::kServiceName,
+                        json_parser_.BindNewPipeAndPassReceiver());
+    json_parser_.set_disconnect_handler(base::BindOnce(
         [](JsonConfigConverter* const loader) { loader->json_parser_.reset(); },
         base::Unretained(this)));
   }
 
-  return *json_parser_;
+  return json_parser_.get();
 }
 
 }  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.h b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.h
index c746ceb..b45aa247a 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.h
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.h
@@ -11,6 +11,7 @@
 #include "base/macros.h"
 #include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.h"
 #include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_config.pb.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/data_decoder/public/mojom/json_parser.mojom.h"
 #include "services/service_manager/public/cpp/connector.h"
 
@@ -58,7 +59,7 @@
  private:
   // Create or reuse a connection to the data decoder service for safe JSON
   // parsing.
-  data_decoder::mojom::JsonParser& GetJsonParser();
+  data_decoder::mojom::JsonParser* GetJsonParser();
 
   // Callback for parser.
   void OnJsonParsed(OnConfigLoadedCallback callback,
@@ -69,7 +70,7 @@
   std::string model_identifier_;
 
   service_manager::Connector* connector_;
-  data_decoder::mojom::JsonParserPtr json_parser_;
+  mojo::Remote<data_decoder::mojom::JsonParser> json_parser_;
 };
 
 }  // namespace app_list
diff --git a/chrome/browser/ui/ash/launcher/arc_app_launcher_browsertest.cc b/chrome/browser/ui/ash/launcher/arc_app_launcher_browsertest.cc
index 4293e78..6eab681 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_launcher_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/arc_app_launcher_browsertest.cc
@@ -236,6 +236,9 @@
 
   void SendPackageRemoved(const std::string& package_name) {
     app_host()->OnPackageRemoved(package_name);
+
+    // Ensure async callbacks from the resulting observer calls are run.
+    base::RunLoop().RunUntilIdle();
   }
 
   void SendInstallationStarted(const std::string& package_name) {
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index c650257..c014442 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -39,6 +39,7 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
+#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/arc_apps.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/crostini/crostini_test_helper.h"
@@ -278,7 +279,19 @@
 class ChromeLauncherControllerTest : public BrowserWithTestWindowTest {
  protected:
   ChromeLauncherControllerTest()
-      : BrowserWithTestWindowTest(Browser::TYPE_NORMAL) {}
+      : BrowserWithTestWindowTest(Browser::TYPE_NORMAL) {
+    if (!base::FeatureList::IsEnabled(features::kAppServiceAsh) &&
+        !base::FeatureList::IsEnabled(features::kAppServiceShelf)) {
+      return;
+    }
+
+    // We set some state to affect what ChromeLauncherControllerTest::SetUp
+    // does, making it set app_service_proxy_connector_ for app_service_proxy_.
+    app_service_ = std::make_unique<apps::AppService>(
+        test_connector_factory_.RegisterInstance(apps::mojom::kServiceName));
+    app_service_proxy_connector_ =
+        test_connector_factory_.GetDefaultConnector();
+  }
 
   ~ChromeLauncherControllerTest() override {}
 
@@ -300,6 +313,11 @@
     manifest.SetString(extensions::manifest_keys::kDescription,
                        "for testing pinned apps");
 
+    // AppService checks the app's type, so sets the type in manifest for
+    // extensions.
+    if (base::FeatureList::IsEnabled(features::kAppServiceShelf))
+      manifest.SetString(extensions::manifest_keys::kLaunchWebURL, kWebAppUrl);
+
     base::DictionaryValue manifest_platform_app;
     manifest_platform_app.SetString(extensions::manifest_keys::kName,
                                     "launcher controller test platform app");
@@ -325,25 +343,19 @@
     DCHECK(profile());
     extension_registry_ = extensions::ExtensionRegistry::Get(profile());
 
-    bool flush_app_service_mojo_calls = false;
     if (app_service_proxy_connector_) {
       DCHECK(profile());
-      app_service_proxy_.reset(apps::AppServiceProxy::CreateForTesting(
-          profile(), app_service_proxy_connector_));
-      old_app_service_proxy_for_testing_ =
-          AppServiceAppModelBuilder::SetAppServiceProxyForTesting(
-              app_service_proxy_.get());
-      // Flush the App Service Mojo calls, but only after calling
-      // arc_test_.SetUp, as it also pumps the run-loop in general.
-      flush_app_service_mojo_calls = true;
+      app_service_proxy_ =
+          apps::AppServiceProxyFactory::GetForProfile(profile());
+      app_service_proxy_->ReInitializeForTesting(profile(),
+                                                 app_service_proxy_connector_);
+      // Allow async callbacks to run.
+      WaitForAppService();
     }
 
     if (auto_start_arc_test_)
       arc_test_.SetUp(profile());
 
-    if (flush_app_service_mojo_calls)
-      app_service_proxy_->FlushMojoCallsForTesting();
-
     // Wait until |extension_system| is signaled as started.
     base::RunLoop run_loop;
     extension_system->ready().Post(FROM_HERE, run_loop.QuitClosure());
@@ -485,12 +497,11 @@
 
   void TearDown() override {
     arc_test_.TearDown();
-    if (app_service_proxy_) {
-      AppServiceAppModelBuilder::SetAppServiceProxyForTesting(
-          old_app_service_proxy_for_testing_);
-      app_service_proxy_.reset(nullptr);
-    }
     launcher_controller_ = nullptr;
+
+    if (app_service_proxy_connector_)
+      app_service_.reset(nullptr);
+
     BrowserWithTestWindowTest::TearDown();
   }
 
@@ -945,6 +956,22 @@
     prefs->OnTaskDestroyed(task_id);
   }
 
+  // Allow AppService async callbacks to run.
+  void WaitForAppService() { base::RunLoop().RunUntilIdle(); }
+
+  // Add extension and allow AppService async callbacks to run.
+  void AddExtension(const Extension* extension) {
+    extension_service_->AddExtension(extension);
+    WaitForAppService();
+  }
+
+  // Remove extension and allow AppService async callbacks to run.
+  void UnloadExtension(const std::string& extension_id,
+                       UnloadedExtensionReason reason) {
+    extension_service_->UnloadExtension(extension_id, reason);
+    WaitForAppService();
+  }
+
   // Needed for extension service & friends to work.
   scoped_refptr<Extension> extension_chrome_;
   scoped_refptr<Extension> extension1_;
@@ -975,8 +1002,10 @@
   app_list::AppListSyncableService* app_list_syncable_service_ = nullptr;
 
   service_manager::Connector* app_service_proxy_connector_ = nullptr;
-  std::unique_ptr<apps::AppServiceProxy> app_service_proxy_;
-  apps::AppServiceProxy* old_app_service_proxy_for_testing_ = nullptr;
+  apps::AppServiceProxy* app_service_proxy_ = nullptr;
+
+  service_manager::TestConnectorFactory test_connector_factory_;
+  std::unique_ptr<service_manager::Service> app_service_;
 
  private:
   TestBrowserWindow* CreateTestBrowserWindowAura() {
@@ -998,19 +1027,6 @@
  protected:
   ChromeLauncherControllerWithArcTest() {
     auto_start_arc_test_ = true;
-    if (!base::FeatureList::IsEnabled(features::kAppServiceAsh)) {
-      return;
-    }
-    // We set some state in the ChromeLauncherControllerTest superclass to
-    // affect what ChromeLauncherControllerTest::SetUp does, making it call
-    // AppServiceAppModelBuilder::SetAppServiceProxyForTesting (ASAMB::SASPFT).
-    // We can only call SASPFT after the TestingProfile is created (which
-    // happens in the superclass' SetUp) but before the ASAMB is constructed
-    // (which also happens in the superclass' SetUp).
-    app_service_ = std::make_unique<apps::AppService>(
-        test_connector_factory_.RegisterInstance(apps::mojom::kServiceName));
-    app_service_proxy_connector_ =
-        test_connector_factory_.GetDefaultConnector();
   }
 
   ~ChromeLauncherControllerWithArcTest() override {}
@@ -1020,24 +1036,9 @@
     ArcAppIcon::DisableSafeDecodingForTesting();
 
     ChromeLauncherControllerTest::SetUp();
-    if (app_service_proxy_connector_) {
-      arc_apps_.reset(
-          apps::ArcApps::CreateForTesting(profile(), app_service_proxy_.get()));
-    }
-  }
-
-  void TearDown() override {
-    if (app_service_proxy_connector_) {
-      arc_apps_.reset(nullptr);
-    }
-    ChromeLauncherControllerTest::TearDown();
   }
 
  private:
-  service_manager::TestConnectorFactory test_connector_factory_;
-  std::unique_ptr<service_manager::Service> app_service_;
-  std::unique_ptr<apps::ArcApps> arc_apps_;
-
   DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerWithArcTest);
 };
 
@@ -1343,15 +1344,15 @@
   // default apps appear on shelf between manually pinned App1.
 
   // Prefs are not yet synced. No default pin appears.
-  extension_service_->AddExtension(extensionYoutubeApp_.get());
+  AddExtension(extensionYoutubeApp_.get());
   EXPECT_EQ("Chrome, App1", GetPinnedAppStatus());
 
   StartPrefSyncService(syncer::SyncDataList());
   EXPECT_EQ("Chrome, Youtube, App1", GetPinnedAppStatus());
 
-  extension_service_->AddExtension(extensionDocApp_.get());
+  AddExtension(extensionDocApp_.get());
   EXPECT_EQ("Chrome, Doc, Youtube, App1", GetPinnedAppStatus());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_EQ("Chrome, Gmail, Doc, Youtube, App1", GetPinnedAppStatus());
 }
 
@@ -1400,7 +1401,7 @@
       {std::pair<std::string, std::string>("app_count", "10")});
 
   // Trigger layout update, app_id does not matter.
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
 
   EXPECT_EQ(
       "Chrome, Gmail, Calendar, Doc, Sheets, Slides, Files, Camera, Photos, "
@@ -1423,7 +1424,7 @@
 
     // Trigger layout update, app_id does not matter. Experiment is still
     // forced.
-    extension_service_->AddExtension(extension1_.get());
+    AddExtension(extension1_.get());
 
     // Youtube is included into default but not to expermenetal. Refreshing
     // should not affect layout.
@@ -1431,7 +1432,7 @@
   }
 
   // Re-update but experiment is off now. No change to layout.
-  extension_service_->AddExtension(extension2_.get());
+  AddExtension(extension2_.get());
   EXPECT_EQ(expectations, GetPinnedAppStatus());
 }
 
@@ -1447,7 +1448,7 @@
       {std::pair<std::string, std::string>("app_count", "10")});
 
   // Trigger layout update, app_id does not matter.
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
 
   EXPECT_EQ("Chrome, Gmail, Doc, Play Store", GetPinnedAppStatus());
 }
@@ -1466,6 +1467,7 @@
   extension_service_->AddExtension(extension1_.get());
   extension_service_->AddExtension(extension2_.get());
   extension_service_->AddExtension(extensionGmailApp_.get());
+  WaitForAppService();
 
   // extension 1, 3 are pinned by user
   syncer::SyncChangeList sync_list;
@@ -1501,6 +1503,7 @@
 
   // Pins must be automatically updated.
   SendListOfArcApps();
+  WaitForAppService();
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id()));
   EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id1));
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id()));
@@ -1519,8 +1522,7 @@
   EXPECT_EQ("App2, Fake App 1, Chrome, App1, Fake App 0, Gmail",
             GetPinnedAppStatus());
 
-  if (app_service_proxy_)
-    app_service_proxy_->FlushMojoCallsForTesting();
+  WaitForAppService();
   copy_sync_list = app_list_syncable_service_->GetAllSyncData(syncer::APP_LIST);
 
   ResetLauncherController();
@@ -1550,6 +1552,7 @@
   EnablePlayStore(true);
 
   SendListOfArcApps();
+  WaitForAppService();
 
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id()));
   EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id1));
@@ -1589,7 +1592,7 @@
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionDocApp_->id()));
   // install extension 2 and check
-  extension_service_->AddExtension(extension2_.get());
+  AddExtension(extension2_.get());
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id()));
 
   // Check user can manually pin or unpin these apps
@@ -1627,20 +1630,20 @@
   // Installing |extensionGmailApp_| should add it to the shelf - behind the
   // chrome icon.
   ash::ShelfItem item;
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id()));
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id()));
   EXPECT_EQ("Chrome, Gmail", GetPinnedAppStatus());
 
   // Installing |extension2_| should add it to the launcher - behind the
   // chrome icon, but in first location.
-  extension_service_->AddExtension(extension2_.get());
+  AddExtension(extension2_.get());
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id()));
   EXPECT_EQ("Chrome, App2, Gmail", GetPinnedAppStatus());
 
   // Installing |extension1_| should add it to the launcher - behind the
   // chrome icon, but in first location.
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
   EXPECT_EQ("Chrome, App1, App2, Gmail", GetPinnedAppStatus());
 }
 
@@ -1664,20 +1667,20 @@
 
   // Installing |extension2_| should add it to the launcher - behind the
   // chrome icon.
-  extension_service_->AddExtension(extension2_.get());
+  AddExtension(extension2_.get());
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id()));
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   EXPECT_EQ("Chrome, App2", GetPinnedAppStatus());
 
   // Installing |extension1_| should add it to the launcher - behind the
   // chrome icon, but in first location.
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   EXPECT_EQ("Chrome, App1, App2", GetPinnedAppStatus());
 
   // Installing |extensionGmailApp_| should add it to the launcher - behind the
   // chrome icon, but in first location.
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_EQ("Chrome, App1, App2, Gmail", GetPinnedAppStatus());
 }
 
@@ -1703,20 +1706,20 @@
   // Installing |extension2_| should add it to the shelf - behind the
   // chrome icon.
   ash::ShelfItem item;
-  extension_service_->AddExtension(extension2_.get());
+  AddExtension(extension2_.get());
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id()));
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   EXPECT_EQ("Chrome, App2", GetPinnedAppStatus());
 
   // Installing |extension1_| should add it to the launcher - behind the
   // chrome icon, but in first location.
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   EXPECT_EQ("App1, Chrome, App2", GetPinnedAppStatus());
 
   // Installing |extensionGmailApp_| should add it to the launcher - behind the
   // chrome icon, but in first location.
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_EQ("App1, Chrome, App2, Gmail", GetPinnedAppStatus());
 }
 
@@ -1731,11 +1734,11 @@
   SendPinChanges(sync_list0, true);
 
   // The shelf layout has always one static item at the beginning (App List).
-  extension_service_->AddExtension(extension2_.get());
+  AddExtension(extension2_.get());
   EXPECT_EQ("Chrome, App2", GetPinnedAppStatus());
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
   EXPECT_EQ("Chrome, App1, App2", GetPinnedAppStatus());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_EQ("Chrome, App1, App2, Gmail", GetPinnedAppStatus());
 
   // Change the order with increasing chrome position and decreasing position.
@@ -1764,17 +1767,14 @@
   EXPECT_EQ("Chrome, Gmail, App2, App1", GetPinnedAppStatus());
 
   // Check that unloading of extensions works as expected.
-  extension_service_->UnloadExtension(extension1_->id(),
-                                      UnloadedExtensionReason::UNINSTALL);
+  UnloadExtension(extension1_->id(), UnloadedExtensionReason::UNINSTALL);
   EXPECT_EQ("Chrome, Gmail, App2", GetPinnedAppStatus());
 
-  extension_service_->UnloadExtension(extension2_->id(),
-                                      UnloadedExtensionReason::UNINSTALL);
+  UnloadExtension(extension2_->id(), UnloadedExtensionReason::UNINSTALL);
   EXPECT_EQ("Chrome, Gmail", GetPinnedAppStatus());
 
   // Check that an update of an extension does not crash the system.
-  extension_service_->UnloadExtension(extensionGmailApp_->id(),
-                                      UnloadedExtensionReason::UPDATE);
+  UnloadExtension(extensionGmailApp_->id(), UnloadedExtensionReason::UPDATE);
   EXPECT_EQ("Chrome, Gmail", GetPinnedAppStatus());
 }
 
@@ -2843,16 +2843,16 @@
   SendPinChanges(sync_list, true);
 
   // The shelf layout has always one static item at the beginning (App List).
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
   EXPECT_EQ("Chrome, App1", GetPinnedAppStatus());
-  extension_service_->AddExtension(extension2_.get());
+  AddExtension(extension2_.get());
   // No new app icon will be generated.
   EXPECT_EQ("Chrome, App1", GetPinnedAppStatus());
 
   // Set the app status as running, which will add an unpinned item.
   launcher_controller_->SetV1AppStatus(extension2_->id(), ash::STATUS_RUNNING);
   EXPECT_EQ("Chrome, App1, app2", GetPinnedAppStatus());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_EQ("Chrome, App1, Gmail, app2", GetPinnedAppStatus());
 
   // Now request to pin all items, which will pin the running unpinned items.
@@ -2889,15 +2889,15 @@
   InsertAddPinChange(&sync_list0, 1, extensionGmailApp_->id());
   SendPinChanges(sync_list0, true);
   // The shelf layout has always one static item at the beginning (app List).
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
   EXPECT_EQ("Chrome, App1", GetPinnedAppStatus());
-  extension_service_->AddExtension(extension_platform_app_.get());
+  AddExtension(extension_platform_app_.get());
   // No new app icon will be generated.
   EXPECT_EQ("Chrome, App1", GetPinnedAppStatus());
   // Add an unpinned but running V2 app.
   CreateRunningV2App(extension_platform_app_->id());
   EXPECT_EQ("Chrome, App1, *platform_app", GetPinnedAppStatus());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_EQ("Chrome, App1, Gmail, *platform_app", GetPinnedAppStatus());
 
   // Now request to pin all items, which should pin the running unpinned item.
@@ -3033,7 +3033,7 @@
 
   // Installing |extension1_| should add it to the launcher. Note, App1 goes
   // before App2 that is aligned with the pin order in policy.
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
   EXPECT_EQ("Chrome, App1, App2", GetPinnedAppStatus());
 
   // Removing |extension1_| from the policy should not be reflected in the
@@ -3090,8 +3090,7 @@
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionDocApp_->id()));
 
-  extension_service_->UnloadExtension(extensionGmailApp_->id(),
-                                      UnloadedExtensionReason::UNINSTALL);
+  UnloadExtension(extensionGmailApp_->id(), UnloadedExtensionReason::UNINSTALL);
 
   EXPECT_FALSE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionDocApp_->id()));
@@ -3186,7 +3185,7 @@
   EXPECT_EQ(expected_pinned_apps, actual_pinned_apps);
 
   // Install |extension2| and verify it shows up between the other two.
-  extension_service_->AddExtension(extension2_.get());
+  AddExtension(extension2_.get());
   expected_pinned_apps.insert(expected_pinned_apps.begin() + 1,
                               extension2_->id());
   GetPinnedAppIds(launcher_controller_.get(), &actual_pinned_apps);
@@ -3305,7 +3304,7 @@
 
   // Installing |extensionGmailApp_| pins it to the launcher.
   const ash::ShelfID gmail_id(extensionGmailApp_->id());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(kGmailUrl));
 
@@ -3362,7 +3361,7 @@
 
   // Installing |extensionGmailApp_| pins it to the launcher.
   const ash::ShelfID gmail_id(extensionGmailApp_->id());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
   launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(kGmailUrl));
 
@@ -3780,13 +3779,14 @@
   // Add |extensionGmailApp_| to the launcher and add two items.
   GURL gmail = GURL("https://mail.google.com/mail/u");
   const ash::ShelfID gmail_id(extensionGmailApp_->id());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(kGmailUrl));
   base::string16 title1 = ASCIIToUTF16("Test1");
   NavigateAndCommitActiveTabWithTitle(browser(), GURL(kGmailUrl), title1);
   chrome::NewTab(browser());
   base::string16 title2 = ASCIIToUTF16("Test2");
   NavigateAndCommitActiveTabWithTitle(browser(), GURL(kGmailUrl), title2);
+  WaitForAppService();
 
   // Check that the menu is properly set.
   ash::ShelfItem item_gmail;
@@ -3828,13 +3828,14 @@
 
   // Add |extensionGmailApp_| to the launcher and add two items.
   const ash::ShelfID gmail_id(extensionGmailApp_->id());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(kGmailUrl));
   base::string16 title1 = ASCIIToUTF16("Test1");
   NavigateAndCommitActiveTabWithTitle(browser(), GURL(kGmailUrl), title1);
   chrome::NewTab(browser());
   base::string16 title2 = ASCIIToUTF16("Test2");
   NavigateAndCommitActiveTabWithTitle(browser(), GURL(kGmailUrl), title2);
+  WaitForAppService();
 
   // Check that the menu is properly set.
   ash::ShelfItem item_gmail;
@@ -3882,7 +3883,7 @@
 
   // Installing |extensionGmailApp_| pins it to the launcher.
   const ash::ShelfID gmail_id(extensionGmailApp_->id());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
 
   // Check that it is now handled.
@@ -3911,7 +3912,7 @@
 
   // Installing |extensionGmailApp_| pins it to the launcher.
   const ash::ShelfID gmail_id(extensionGmailApp_->id());
-  extension_service_->AddExtension(extensionGmailApp_.get());
+  AddExtension(extensionGmailApp_.get());
   EXPECT_TRUE(launcher_controller_->IsAppPinned(extensionGmailApp_->id()));
 
   // The content should not be able to be handled by the app.
@@ -4728,7 +4729,7 @@
   crostini::CrostiniTestHelper test_helper(profile());
   // TODO(crubug.com/918739): Fix pins are not refreshed on enabling Crostini.
   // As a workaround add any app that triggers pin update.
-  extension_service_->AddExtension(extension1_.get());
+  AddExtension(extension1_.get());
   EXPECT_EQ("Chrome, Terminal", GetPinnedAppStatus());
 
   // Unpin the Terminal
diff --git a/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc
index 34317f4..2c77fc9 100644
--- a/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc
@@ -317,7 +317,7 @@
   test_stored_forms().push_back(&saved_match());
   test_stored_forms().push_back(&psl_match());
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnPendingPassword(std::move(test_form_manager));
 
   EXPECT_THAT(passwords_data().GetCurrentForms(),
@@ -332,7 +332,7 @@
 TEST_F(ManagePasswordsStateTest, PasswordSaved) {
   test_stored_forms().push_back(&saved_match());
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnPendingPassword(std::move(test_form_manager));
   EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE,
             passwords_data().state());
@@ -349,7 +349,7 @@
 TEST_F(ManagePasswordsStateTest, PasswordSubmittedFederationsPresent) {
   std::unique_ptr<PasswordFormManager> test_form_manager(
       CreateFormManagerWithFederation());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnPendingPassword(std::move(test_form_manager));
 
   EXPECT_THAT(passwords_data().GetCurrentForms(),
@@ -422,7 +422,7 @@
   test_stored_forms().push_back(&saved_match());
   std::unique_ptr<PasswordFormManager> test_form_manager(
       CreateFormManagerWithFederation());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
 
   passwords_data().OnAutomaticPasswordSave(std::move(test_form_manager));
   EXPECT_THAT(passwords_data().GetCurrentForms(),
@@ -505,7 +505,7 @@
 
 TEST_F(ManagePasswordsStateTest, OnInactive) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
 
   passwords_data().OnPendingPassword(std::move(test_form_manager));
   EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE,
@@ -520,7 +520,7 @@
 
 TEST_F(ManagePasswordsStateTest, PendingPasswordAddBlacklisted) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnPendingPassword(std::move(test_form_manager));
   EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE,
             passwords_data().state());
@@ -553,7 +553,7 @@
 
 TEST_F(ManagePasswordsStateTest, AutomaticPasswordSaveAddBlacklisted) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnAutomaticPasswordSave(std::move(test_form_manager));
   EXPECT_EQ(password_manager::ui::CONFIRMATION_STATE, passwords_data().state());
 
@@ -573,7 +573,7 @@
 
 TEST_F(ManagePasswordsStateTest, PasswordUpdateAddBlacklisted) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnUpdatePassword(std::move(test_form_manager));
   EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE,
             passwords_data().state());
@@ -585,7 +585,7 @@
   test_stored_forms().push_back(&saved_match());
   test_stored_forms().push_back(&psl_match());
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnUpdatePassword(std::move(test_form_manager));
 
   EXPECT_THAT(passwords_data().GetCurrentForms(),
@@ -605,7 +605,7 @@
   android_form.password_value = base::ASCIIToUTF16("old pass");
   test_stored_forms().push_back(&android_form);
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnUpdatePassword(std::move(test_form_manager));
 
   EXPECT_THAT(passwords_data().GetCurrentForms(),
@@ -622,7 +622,7 @@
   test_stored_forms().push_back(&saved_match());
   std::unique_ptr<PasswordFormManager> test_form_manager(
       CreateFormManagerWithFederation());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   passwords_data().OnUpdatePassword(std::move(test_form_manager));
 
   EXPECT_THAT(passwords_data().GetCurrentForms(),
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index 13ff2186..6945b91 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -343,7 +343,7 @@
 
   // Set the bubble state to |state|.
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   if (state == password_manager::ui::PENDING_PASSWORD_STATE)
     controller()->OnPasswordSubmitted(std::move(test_form_manager));
@@ -389,7 +389,7 @@
 
 TEST_F(ManagePasswordsUIControllerTest, PasswordSubmitted) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
   EXPECT_TRUE(controller()->opened_automatic_bubble());
@@ -421,7 +421,7 @@
   stats[0].username_value = test_local_form().username_value;
   stats[0].dismissal_count = kGreatDissmisalCount;
   fetcher().set_stats(stats);
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
   EXPECT_FALSE(controller()->opened_automatic_bubble());
@@ -440,7 +440,7 @@
   stats[0].username_value = ASCIIToUTF16("not my username");
   stats[0].dismissal_count = kGreatDissmisalCount;
   fetcher().set_stats(stats);
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
   EXPECT_TRUE(controller()->opened_automatic_bubble());
@@ -461,7 +461,7 @@
   controller->set_client(&client());
 
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   // The bubble is ready to open but the tab is inactive. Therefore, we don't
   // call UpdateIconAndBubbleState here.
   controller->OnPasswordSubmitted(std::move(test_form_manager));
@@ -476,7 +476,7 @@
 
 TEST_F(ManagePasswordsUIControllerTest, PasswordSaved) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
 
@@ -515,7 +515,7 @@
     // Exercise controller.
     std::unique_ptr<PasswordFormManager> test_form_manager(
         CreateFormManagerWithMetricsRecorder(recorder));
-    test_form_manager->ProvisionallySave(submitted_form(), &driver());
+    test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
     EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
     controller()->OnPasswordSubmitted(std::move(test_form_manager));
 
@@ -573,7 +573,7 @@
 
 TEST_F(ManagePasswordsUIControllerTest, PasswordBlacklisted) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
 
@@ -587,7 +587,7 @@
   std::unique_ptr<PasswordFormManager> test_form_manager(
       CreateFormManagerWithBestMatches(observed_form(), {&test_local_form()},
                                        nullptr));
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
 
@@ -613,7 +613,7 @@
 
 TEST_F(ManagePasswordsUIControllerTest, NormalNavigationsClosedBubble) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
   controller()->SavePassword(test_local_form().username_value,
@@ -637,7 +637,7 @@
       ->NavigateAndCommit(GURL("chrome://sign-in"));
 
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
   EXPECT_EQ(GURL::EmptyGURL(), controller()->GetOrigin());
@@ -917,7 +917,7 @@
 
 TEST_F(ManagePasswordsUIControllerTest, PasswordUpdated) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnUpdatePasswordSubmitted(std::move(test_form_manager));
 
@@ -984,7 +984,7 @@
     std::unique_ptr<PasswordFormManager> test_form_manager(
         CreateFormManagerWithMetricsRecorder(recorder));
 
-    test_form_manager->ProvisionallySave(submitted_form(), &driver());
+    test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
     EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()).Times(3);
     controller()->OnShowManualFallbackForSaving(
         std::move(test_form_manager), false /* has_generated_password */,
@@ -1037,7 +1037,7 @@
                                          nullptr));
 
     // Simulate user typing a password.
-    test_form_manager->ProvisionallySave(submitted_form(), &driver());
+    test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
 
     EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
     controller()->OnShowManualFallbackForSaving(
@@ -1067,7 +1067,7 @@
       CreateFormManagerWithBestMatches(observed_form(), {}, nullptr));
 
   // Simulate user typing a password.
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
 
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnShowManualFallbackForSaving(
@@ -1092,7 +1092,7 @@
     ManagePasswordsUIController::set_save_fallback_timeout_in_seconds(0);
 
     std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-    test_form_manager->ProvisionallySave(submitted_form(), &driver());
+    test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
 
     EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
     controller()->OnShowManualFallbackForSaving(
@@ -1129,7 +1129,7 @@
 
     ManagePasswordsUIController::set_save_fallback_timeout_in_seconds(0);
     std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-    test_form_manager->ProvisionallySave(submitted_form(), &driver());
+    test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
 
     EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
     controller()->OnShowManualFallbackForSaving(
@@ -1169,7 +1169,7 @@
 TEST_F(ManagePasswordsUIControllerTest,
        ManualFallbackForSavingFollowedByAutomaticBubble) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
 
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnShowManualFallbackForSaving(
@@ -1186,7 +1186,7 @@
   FormData form = submitted_form();
   form.fields[0].value = ASCIIToUTF16("some_other_username");
   form.fields[1].value = ASCIIToUTF16("password123");
-  test_form_manager->ProvisionallySave(form, &driver());
+  test_form_manager->ProvisionallySave(form, &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()).Times(0);
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
 
@@ -1206,7 +1206,7 @@
     std::unique_ptr<PasswordFormManager> test_form_manager(
         CreateFormManagerWithBestMatches(observed_form(), {&test_local_form()},
                                          nullptr));
-    test_form_manager->ProvisionallySave(submitted_form(), &driver());
+    test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
     EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
     controller()->OnShowManualFallbackForSaving(
         std::move(test_form_manager), true /* has_generated_password */, false);
@@ -1228,7 +1228,7 @@
 
 TEST_F(ManagePasswordsUIControllerTest, AutofillDuringSignInPromo) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
 
@@ -1251,7 +1251,7 @@
 
 TEST_F(ManagePasswordsUIControllerTest, AuthenticateUserToRevealPasswords) {
   std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager());
-  test_form_manager->ProvisionallySave(submitted_form(), &driver());
+  test_form_manager->ProvisionallySave(submitted_form(), &driver(), nullptr);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
   EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE,
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
index 7d64702..4f2b015 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
@@ -27,6 +27,8 @@
 #include "components/autofill/core/browser/data_model/credit_card.h"
 #include "components/constrained_window/constrained_window_views.h"
 #include "components/payments/content/payment_request.h"
+#include "components/payments/core/features.h"
+#include "components/payments/core/payments_experimental_features.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
@@ -246,10 +248,8 @@
 
   HideProcessingSpinner();
 
-  if (request_->state()->are_requested_methods_supported() &&
-      observer_for_testing_) {
-    observer_for_testing_->OnDialogOpened();
-  }
+  if (request_->state()->are_requested_methods_supported())
+    OnDialogOpened();
 }
 
 void PaymentRequestDialogView::Pay() {
@@ -417,6 +417,23 @@
       request_->web_contents()->GetBrowserContext());
 }
 
+void PaymentRequestDialogView::OnDialogOpened() {
+  if (request_->spec()->request_shipping() &&
+      !request_->state()->selected_shipping_profile() &&
+      PaymentsExperimentalFeatures::IsEnabled(
+          features::kStrictHasEnrolledAutofillInstrument)) {
+    view_stack_->Push(
+        CreateViewAndInstallController(
+            ProfileListViewController::GetShippingProfileViewController(
+                request_->spec(), request_->state(), this),
+            &controller_map_),
+        /* animate = */ false);
+  }
+
+  if (observer_for_testing_)
+    observer_for_testing_->OnDialogOpened();
+}
+
 void PaymentRequestDialogView::ShowInitialPaymentSheet() {
   view_stack_->Push(CreateViewAndInstallController(
                         std::make_unique<PaymentSheetViewController>(
@@ -427,10 +444,8 @@
   if (number_of_initialization_tasks_ > 0)
     return;
 
-  if (request_->state()->are_requested_methods_supported() &&
-      observer_for_testing_) {
-    observer_for_testing_->OnDialogOpened();
-  }
+  if (request_->state()->are_requested_methods_supported())
+    OnDialogOpened();
 }
 
 void PaymentRequestDialogView::SetupSpinnerOverlay() {
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.h b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
index d6d57f7..b01db97 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.h
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
@@ -183,6 +183,7 @@
   views::View* throbber_overlay_for_testing() { return throbber_overlay_; }
 
  private:
+  void OnDialogOpened();
   void ShowInitialPaymentSheet();
   void SetupSpinnerOverlay();
 
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
index ce5eb34..ae1bc4b 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -67,6 +67,8 @@
       delegate_(delegate) {
   SetInkDropMode(InkDropMode::ON);
   set_has_ink_drop_action_on_click(true);
+  set_hide_ink_drop_when_showing_context_menu(false);
+  set_show_ink_drop_when_hot_tracked(true);
   SetID(VIEW_ID_BROWSER_ACTION);
   view_controller_->SetDelegate(this);
   SetHorizontalAlignment(gfx::ALIGN_CENTER);
@@ -272,23 +274,6 @@
   MenuButton::ViewHierarchyChanged(details);
 }
 
-void ToolbarActionView::StateChanged(views::Button::ButtonState old_state) {
-  MenuButton::StateChanged(old_state);
-  if (delegate_->ShownInsideMenu()) {
-    // The following code is necessary to ensure the item is properly
-    // highlighted when using keyboard navigation to select items in the menu.
-    // InkDrops will listen for hover events and highlight accordingly. However,
-    // menu items don't actually get focus so using SetShowHighlightOnFocus()
-    // won't work. The button state is set to STATE_HOVERED, so this code will
-    // ensure the InkDrop actually highlights.
-    views::InkDropState target_state = state() == views::Button::STATE_HOVERED
-                                           ? views::InkDropState::ACTIVATED
-                                           : views::InkDropState::HIDDEN;
-    if (GetInkDrop()->GetTargetInkDropState() != target_state)
-      AnimateInkDrop(target_state, nullptr);
-  }
-}
-
 views::View* ToolbarActionView::GetAsView() {
   return this;
 }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.h b/chrome/browser/ui/views/toolbar/toolbar_action_view.h
index 92cf648..6a52d59 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_action_view.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.h
@@ -108,7 +108,6 @@
   void OnDragDone() override;
   void ViewHierarchyChanged(
       const views::ViewHierarchyChangedDetails& details) override;
-  void StateChanged(views::Button::ButtonState old_state) override;
 
   // ToolbarActionViewDelegateViews:
   views::View* GetAsView() override;
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index ee389c1..dd3bdfa 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -33,6 +33,7 @@
 #include "chrome/browser/chromeos/language_preferences.h"
 #include "chrome/browser/chromeos/login/lock_screen_utils.h"
 #include "chrome/browser/chromeos/login/reauth_stats.h"
+#include "chrome/browser/chromeos/login/saml/public_saml_url_fetcher.h"
 #include "chrome/browser/chromeos/login/screens/network_error.h"
 #include "chrome/browser/chromeos/login/signin_partition_manager.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
@@ -365,10 +366,29 @@
   login::SigninPartitionManager* signin_partition_manager =
       login::SigninPartitionManager::Factory::GetForBrowserContext(
           Profile::FromWebUI(web_ui()));
-  signin_partition_manager->StartSigninSession(
-      web_ui()->GetWebContents(),
+
+  auto partition_call = base::BindOnce(
+      &login::SigninPartitionManager::StartSigninSession,
+      base::Unretained(signin_partition_manager), web_ui()->GetWebContents(),
       base::BindOnce(&GaiaScreenHandler::LoadGaiaWithPartition,
                      weak_factory_.GetWeakPtr(), context));
+
+  if (!context.email.empty()) {
+    const AccountId account_id = GetAccountId(
+        context.email, std::string() /* id */, AccountType::UNKNOWN);
+    const user_manager::User* const user =
+        user_manager::UserManager::Get()->FindUser(account_id);
+
+    if (user && user->using_saml() &&
+        user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
+      public_saml_url_fetcher_ =
+          std::make_unique<chromeos::PublicSamlUrlFetcher>(account_id);
+      public_saml_url_fetcher_->Fetch(std::move(partition_call));
+      return;
+    }
+  }
+  public_saml_url_fetcher_.reset();
+  std::move(partition_call).Run();
 }
 
 void GaiaScreenHandler::LoadGaiaWithPartition(
@@ -444,30 +464,6 @@
   screen_mode_ = GetGaiaScreenMode(context.email, context.use_offline);
   params.SetInteger("screenMode", screen_mode_);
 
-  if (!context.email.empty()) {
-    const AccountId account_id = GetAccountId(
-        context.email, std::string() /* id */, AccountType::UNKNOWN);
-    const user_manager::User* const user =
-        user_manager::UserManager::Get()->FindUser(account_id);
-    if (user && user->using_saml() &&
-        user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT &&
-        base::CommandLine::ForCurrentProcess()->HasSwitch(
-            switches::kPublicAccountsSamlUrl)) {
-      std::string saml_url =
-          base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-              switches::kPublicAccountsSamlUrl);
-      params.SetBoolean("startsOnSamlPage", true);
-      params.SetString("frameUrl", saml_url);
-      params.SetString("email", account_id.GetUserEmail());
-      CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kPublicAccountsSamlAclUrl));
-      std::string saml_acl_url =
-          base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-              switches::kPublicAccountsSamlAclUrl);
-      params.SetString("samlAclUrl", saml_acl_url);
-    }
-  }
-
   if (screen_mode_ == GAIA_SCREEN_MODE_AD && !authpolicy_login_helper_)
     authpolicy_login_helper_ = std::make_unique<AuthPolicyHelper>();
 
@@ -538,6 +534,26 @@
                     ExtractSamlPasswordAttributesEnabled());
   params.SetBoolean("enableGaiaActionButtons", GaiaActionButtonsEnabled());
 
+  if (public_saml_url_fetcher_) {
+    params.SetBoolean("startsOnSamlPage", true);
+    CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
+        switches::kPublicAccountsSamlAclUrl));
+    std::string saml_acl_url =
+        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+            switches::kPublicAccountsSamlAclUrl);
+    params.SetString("samlAclUrl", saml_acl_url);
+    if (public_saml_url_fetcher_->FetchSucceeded()) {
+      params.SetString("frameUrl", public_saml_url_fetcher_->GetRedirectUrl());
+    } else {
+      // TODO: make the string localized.
+      std::string msg = "Failed to fetch the SAML redirect URL from the server";
+      core_oobe_view_->ShowSignInError(
+          0, msg, std::string(), HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
+      return;
+    }
+  }
+  public_saml_url_fetcher_.reset();
+
   frame_state_ = FRAME_STATE_LOADING;
   CallJS("login.GaiaSigninScreen.loadAuthExtension", params);
 }
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
index 9cba09d9..d460c6c 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -39,6 +39,7 @@
 class SamlPasswordAttributes;
 class SigninScreenHandler;
 class UserContext;
+class PublicSamlUrlFetcher;
 
 class GaiaView {
  public:
@@ -414,6 +415,8 @@
   std::unique_ptr<LoginClientCertUsageObserver>
       extension_provided_client_cert_usage_observer_;
 
+  std::unique_ptr<chromeos::PublicSamlUrlFetcher> public_saml_url_fetcher_;
+
   // State of the security token PIN dialogs:
 
   // Whether this instance is currently registered as a host for showing the
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
index 867c83d..acd4940 100644
--- a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
@@ -183,7 +183,7 @@
 IN_PROC_BROWSER_TEST_F(InterstitialUITest, OriginPolicyErrorInterstitial) {
   TestInterstitial(GURL("chrome://interstitials/origin_policy"),
                    "Origin Policy Error",
-                   base::ASCIIToUTF16("has requested that a security policy"));
+                   base::ASCIIToUTF16("has requested that an origin policy"));
 }
 
 // Tests that back button works after opening an interstitial from
diff --git a/chrome/browser/usb/usb_chooser_context.cc b/chrome/browser/usb/usb_chooser_context.cc
index d38392d..5f8ccef 100644
--- a/chrome/browser/usb/usb_chooser_context.cc
+++ b/chrome/browser/usb/usb_chooser_context.cc
@@ -15,10 +15,13 @@
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/usb/usb_blocklist.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/content_settings/core/common/content_settings.h"
+#include "components/content_settings/core/common/pref_names.h"
 #include "content/public/browser/system_connector.h"
 #include "services/device/public/cpp/usb/usb_ids.h"
 #include "services/device/public/mojom/constants.mojom.h"
@@ -26,6 +29,10 @@
 #include "services/service_manager/public/cpp/connector.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#endif  // defined(OS_CHROMEOS)
+
 namespace {
 
 constexpr char kDeviceNameKey[] = "name";
@@ -130,8 +137,21 @@
                          CONTENT_SETTINGS_TYPE_USB_GUARD,
                          CONTENT_SETTINGS_TYPE_USB_CHOOSER_DATA),
       is_incognito_(profile->IsOffTheRecord()) {
+#if defined(OS_CHROMEOS)
+  bool is_signin_profile = chromeos::ProfileHelper::IsSigninProfile(profile);
+  PrefService* pref_service = is_signin_profile
+                                  ? g_browser_process->local_state()
+                                  : profile->GetPrefs();
+  const char* pref_name =
+      is_signin_profile ? prefs::kDeviceLoginScreenWebUsbAllowDevicesForUrls
+                        : prefs::kManagedWebUsbAllowDevicesForUrls;
+#else   // defined(OS_CHROMEOS)
+  PrefService* pref_service = profile->GetPrefs();
+  const char* pref_name = prefs::kManagedWebUsbAllowDevicesForUrls;
+#endif  // defined(OS_CHROMEOS)
+
   usb_policy_allowed_devices_.reset(
-      new UsbPolicyAllowedDevices(profile->GetPrefs()));
+      new UsbPolicyAllowedDevices(pref_service, pref_name));
 }
 
 // static
diff --git a/chrome/browser/usb/usb_chooser_context_unittest.cc b/chrome/browser/usb/usb_chooser_context_unittest.cc
index f9de110..9817e24 100644
--- a/chrome/browser/usb/usb_chooser_context_unittest.cc
+++ b/chrome/browser/usb/usb_chooser_context_unittest.cc
@@ -14,6 +14,10 @@
 #include "chrome/browser/usb/usb_chooser_context.h"
 #include "chrome/browser/usb/usb_chooser_context_factory.h"
 #include "chrome/browser/usb/usb_chooser_context_mock_device_observer.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/pref_names.h"
@@ -593,6 +597,82 @@
                                          *unrelated_device_info));
 }
 
+#if defined(OS_CHROMEOS)
+
+class DeviceLoginScreenWebUsbChooserContextTest : public UsbChooserContextTest {
+ public:
+  DeviceLoginScreenWebUsbChooserContextTest()
+      : testing_local_state_(TestingBrowserProcess::GetGlobal()) {
+    TestingProfile::Builder builder;
+    builder.SetPath(base::FilePath(FILE_PATH_LITERAL(chrome::kInitialProfile)));
+    signin_profile_ = builder.Build();
+  }
+  ~DeviceLoginScreenWebUsbChooserContextTest() override {}
+
+ protected:
+  Profile* GetSigninProfile() { return signin_profile_.get(); }
+
+ private:
+  ScopedTestingLocalState testing_local_state_;
+  std::unique_ptr<Profile> signin_profile_;
+};
+
+TEST_F(DeviceLoginScreenWebUsbChooserContextTest,
+       UserUsbChooserContextOnlyUsesUserPolicy) {
+  const std::vector<GURL> kValidRequestingOrigins = {kProductVendorUrl,
+                                                     kVendorUrl, kAnyDeviceUrl};
+  const std::vector<GURL> kInvalidRequestingOrigins = {kGadgetUrl, kCoolUrl};
+
+  UsbDeviceInfoPtr specific_device_info = device_manager_.CreateAndAddDevice(
+      6353, 5678, "Google", "Gizmo", "ABC123");
+
+  Profile* user_profile = profile();
+  Profile* signin_profile = GetSigninProfile();
+
+  auto* user_store = GetChooserContext(user_profile);
+  auto* signin_store = GetChooserContext(signin_profile);
+
+  ExpectNoPermissions(user_store, *specific_device_info);
+  ExpectNoPermissions(signin_store, *specific_device_info);
+
+  user_profile->GetPrefs()->Set(
+      prefs::kManagedWebUsbAllowDevicesForUrls,
+      *base::JSONReader::ReadDeprecated(kPolicySetting));
+
+  ExpectCorrectPermissions(user_store, kValidRequestingOrigins,
+                           kInvalidRequestingOrigins, *specific_device_info);
+  ExpectNoPermissions(signin_store, *specific_device_info);
+}
+
+TEST_F(DeviceLoginScreenWebUsbChooserContextTest,
+       SigninUsbChooserContextOnlyUsesDevicePolicy) {
+  const std::vector<GURL> kValidRequestingOrigins = {kProductVendorUrl,
+                                                     kVendorUrl, kAnyDeviceUrl};
+  const std::vector<GURL> kInvalidRequestingOrigins = {kGadgetUrl, kCoolUrl};
+
+  UsbDeviceInfoPtr specific_device_info = device_manager_.CreateAndAddDevice(
+      6353, 5678, "Google", "Gizmo", "ABC123");
+
+  Profile* user_profile = profile();
+  Profile* signin_profile = GetSigninProfile();
+
+  auto* user_store = GetChooserContext(user_profile);
+  auto* signin_store = GetChooserContext(signin_profile);
+
+  ExpectNoPermissions(user_store, *specific_device_info);
+  ExpectNoPermissions(signin_store, *specific_device_info);
+
+  g_browser_process->local_state()->Set(
+      prefs::kDeviceLoginScreenWebUsbAllowDevicesForUrls,
+      *base::JSONReader::ReadDeprecated(kPolicySetting));
+
+  ExpectNoPermissions(user_store, *specific_device_info);
+  ExpectCorrectPermissions(signin_store, kValidRequestingOrigins,
+                           kInvalidRequestingOrigins, *specific_device_info);
+}
+
+#endif  // defined(OS_CHROMEOS)
+
 namespace {
 
 void ExpectDeviceObjectInfo(const base::Value& actual,
diff --git a/chrome/browser/usb/usb_policy_allowed_devices.cc b/chrome/browser/usb/usb_policy_allowed_devices.cc
index bcc26f0..b1298b4 100644
--- a/chrome/browser/usb/usb_policy_allowed_devices.cc
+++ b/chrome/browser/usb/usb_policy_allowed_devices.cc
@@ -10,7 +10,6 @@
 #include "base/bind.h"
 #include "base/strings/string_split.h"
 #include "base/values.h"
-#include "components/content_settings/core/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "services/device/public/mojom/usb_device.mojom.h"
 #include "services/device/public/mojom/usb_manager.mojom.h"
@@ -42,14 +41,15 @@
 
 }  // namespace
 
-UsbPolicyAllowedDevices::UsbPolicyAllowedDevices(PrefService* pref_service) {
+UsbPolicyAllowedDevices::UsbPolicyAllowedDevices(PrefService* pref_service,
+                                                 const char* pref_name)
+    : pref_name_(pref_name) {
   pref_change_registrar_.Init(pref_service);
-  // Add an observer for |kManagedWebUsbAllowDevicesForUrls| to call
-  // CreateOrUpdateMap when the value is changed. The lifetime of
-  // |pref_change_registrar_| is managed by this class, therefore it is safe to
-  // use base::Unretained here.
+  // Add an observer for |pref_name| to call CreateOrUpdateMap when the value is
+  // changed. The lifetime of |pref_change_registrar_| is managed by this class,
+  // therefore it is safe to use base::Unretained here.
   pref_change_registrar_.Add(
-      prefs::kManagedWebUsbAllowDevicesForUrls,
+      pref_name,
       base::BindRepeating(&UsbPolicyAllowedDevices::CreateOrUpdateMap,
                           base::Unretained(this)));
 
@@ -92,8 +92,8 @@
 }
 
 void UsbPolicyAllowedDevices::CreateOrUpdateMap() {
-  const base::Value* pref_value = pref_change_registrar_.prefs()->Get(
-      prefs::kManagedWebUsbAllowDevicesForUrls);
+  const base::Value* pref_value =
+      pref_change_registrar_.prefs()->Get(pref_name_);
   usb_device_ids_to_urls_.clear();
 
   // A policy has not been assigned.
diff --git a/chrome/browser/usb/usb_policy_allowed_devices.h b/chrome/browser/usb/usb_policy_allowed_devices.h
index ae80213..1497744 100644
--- a/chrome/browser/usb/usb_policy_allowed_devices.h
+++ b/chrome/browser/usb/usb_policy_allowed_devices.h
@@ -23,11 +23,12 @@
 class PrefService;
 
 // This class is used to initialize a UsbDeviceIdsToUrlsMap from the
-// preference value for the WebUsbAllowDevicesForUrls policy. The map
-// provides an efficient method of checking if a particular device is allowed to
-// be used by the given requesting and embedding origins. Additionally, this
-// class also uses |pref_change_registrar_| to observe for changes to the
-// preference value so that the map can be updated accordingly.
+// preference value for the WebUsbAllowDevicesForUrls or
+// DeviceLoginScreenWebUsbAllowDevicesForUrls policy. The map provides an
+// efficient method of checking if a particular device is allowed to be used by
+// the given requesting and embedding origins. Additionally, this class also
+// uses |pref_change_registrar_| to observe for changes to the preference value
+// so that the map can be updated accordingly.
 class UsbPolicyAllowedDevices {
  public:
   // A map of device IDs to a set of origins stored in a std::pair. The device
@@ -41,8 +42,8 @@
                std::set<std::pair<url::Origin, base::Optional<url::Origin>>>>;
 
   // Initializes |pref_change_registrar_| with |pref_service| and adds an
-  // an observer for the pref path |kManagedWebUsbAllowDevicesForUrls|.
-  explicit UsbPolicyAllowedDevices(PrefService* pref_service);
+  // an observer for the |pref_name|.
+  UsbPolicyAllowedDevices(PrefService* pref_service, const char* pref_name);
   ~UsbPolicyAllowedDevices();
 
   // Checks if |requesting_origin| (when embedded within |embedding_origin|) is
@@ -58,11 +59,12 @@
 
  private:
   // Creates or updates the |usb_device_ids_to_urls_| map using the
-  // pref at the path |kManagedWebUsbAllowDevicesForUrls|. The existing map is
-  // cleared to ensure that previous pref settings are removed.
+  // pref at |pref_name_|. The existing map is cleared to ensure that previous
+  // pref settings are removed.
   void CreateOrUpdateMap();
 
   // Allow for this class to observe changes to the pref value.
+  const char* pref_name_;
   PrefChangeRegistrar pref_change_registrar_;
   UsbDeviceIdsToUrlsMap usb_device_ids_to_urls_;
 };
diff --git a/chrome/browser/usb/usb_policy_allowed_devices_unittest.cc b/chrome/browser/usb/usb_policy_allowed_devices_unittest.cc
index 9ea6ad9..5527a87 100644
--- a/chrome/browser/usb/usb_policy_allowed_devices_unittest.cc
+++ b/chrome/browser/usb/usb_policy_allowed_devices_unittest.cc
@@ -32,6 +32,11 @@
  protected:
   Profile* profile() { return &profile_; }
 
+  std::unique_ptr<UsbPolicyAllowedDevices> CreateUsbPolicyAllowedDevices() {
+    return std::make_unique<UsbPolicyAllowedDevices>(
+        profile()->GetPrefs(), prefs::kManagedWebUsbAllowDevicesForUrls);
+  }
+
   device::FakeUsbDeviceManager device_manager_;
 
  private:
@@ -39,11 +44,16 @@
   TestingProfile profile_;
 };
 
+std::unique_ptr<base::Value> ReadJson(base::StringPiece json) {
+  base::Optional<base::Value> value = base::JSONReader::Read(json);
+  EXPECT_TRUE(value);
+  return value ? base::Value::ToUniquePtrValue(std::move(*value)) : nullptr;
+}
+
 }  // namespace
 
 TEST_F(UsbPolicyAllowedDevicesTest, InitializeWithMissingPrefValue) {
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   EXPECT_TRUE(usb_policy_allowed_devices->map().empty());
 }
@@ -53,8 +63,7 @@
 
   SetWebUsbAllowDevicesForUrlsPrefValue(pref_value);
 
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   EXPECT_TRUE(usb_policy_allowed_devices->map().empty());
 }
@@ -94,13 +103,11 @@
 }  // namespace
 
 TEST_F(UsbPolicyAllowedDevicesTest, InitializeWithExistingPrefValue) {
-  std::unique_ptr<base::Value> pref_value =
-      base::JSONReader::ReadDeprecated(kPolicySetting);
+  std::unique_ptr<base::Value> pref_value = ReadJson(kPolicySetting);
 
   SetWebUsbAllowDevicesForUrlsPrefValue(*pref_value);
 
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   const UsbPolicyAllowedDevices::UsbDeviceIdsToUrlsMap& map =
       usb_policy_allowed_devices->map();
@@ -132,13 +139,11 @@
 
 TEST_F(UsbPolicyAllowedDevicesTest,
        InitializeWithMissingPolicyThenUpdatePolicy) {
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
   EXPECT_TRUE(usb_policy_allowed_devices->map().empty());
 
   // Ensure that the allowed devices can be dynamically updated.
-  std::unique_ptr<base::Value> pref_value =
-      base::JSONReader::ReadDeprecated(kPolicySetting);
+  std::unique_ptr<base::Value> pref_value = ReadJson(kPolicySetting);
 
   SetWebUsbAllowDevicesForUrlsPrefValue(*pref_value);
 
@@ -172,13 +177,11 @@
 
 TEST_F(UsbPolicyAllowedDevicesTest,
        InitializeWithExistingPolicyThenRemovePolicy) {
-  std::unique_ptr<base::Value> pref_value =
-      base::JSONReader::ReadDeprecated(kPolicySetting);
+  std::unique_ptr<base::Value> pref_value = ReadJson(kPolicySetting);
 
   SetWebUsbAllowDevicesForUrlsPrefValue(*pref_value);
 
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   const UsbPolicyAllowedDevices::UsbDeviceIdsToUrlsMap& map =
       usb_policy_allowed_devices->map();
@@ -234,13 +237,12 @@
 
 TEST_F(UsbPolicyAllowedDevicesTest,
        InitializeWithExistingPrefValueContainingDuplicateDevices) {
-  std::unique_ptr<base::Value> pref_value = base::JSONReader::ReadDeprecated(
-      kPolicySettingWithEntriesContainingDuplicateDevices);
+  std::unique_ptr<base::Value> pref_value =
+      ReadJson(kPolicySettingWithEntriesContainingDuplicateDevices);
 
   SetWebUsbAllowDevicesForUrlsPrefValue(*pref_value);
 
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   const UsbPolicyAllowedDevices::UsbDeviceIdsToUrlsMap& map =
       usb_policy_allowed_devices->map();
@@ -275,13 +277,12 @@
 }  // namespace
 
 TEST_F(UsbPolicyAllowedDevicesTest, IsDeviceAllowed) {
-  std::unique_ptr<base::Value> pref_value = base::JSONReader::ReadDeprecated(
-      kPolicySettingWithEntriesMatchingMultipleDevices);
+  std::unique_ptr<base::Value> pref_value =
+      ReadJson(kPolicySettingWithEntriesMatchingMultipleDevices);
 
   SetWebUsbAllowDevicesForUrlsPrefValue(*pref_value);
 
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   const auto kGoogleOrigin = url::Origin::Create(GURL("https://google.com"));
   const auto kYoutubeOrigin =
@@ -345,13 +346,12 @@
 }
 
 TEST_F(UsbPolicyAllowedDevicesTest, IsDeviceAllowedForUrlsNotInPref) {
-  std::unique_ptr<base::Value> pref_value = base::JSONReader::ReadDeprecated(
-      kPolicySettingWithEntriesMatchingMultipleDevices);
+  std::unique_ptr<base::Value> pref_value =
+      ReadJson(kPolicySettingWithEntriesMatchingMultipleDevices);
 
   SetWebUsbAllowDevicesForUrlsPrefValue(*pref_value);
 
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   const url::Origin origins[] = {
       url::Origin::Create(GURL("https://evil.com")),
@@ -369,13 +369,12 @@
 }
 
 TEST_F(UsbPolicyAllowedDevicesTest, IsDeviceAllowedForDeviceNotInPref) {
-  std::unique_ptr<base::Value> pref_value = base::JSONReader::ReadDeprecated(
-      kPolicySettingWithEntriesMatchingMultipleDevices);
+  std::unique_ptr<base::Value> pref_value =
+      ReadJson(kPolicySettingWithEntriesMatchingMultipleDevices);
 
   SetWebUsbAllowDevicesForUrlsPrefValue(*pref_value);
 
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   const url::Origin origins[] = {
       url::Origin::Create(GURL("https://google.com")),
@@ -407,13 +406,12 @@
 
 TEST_F(UsbPolicyAllowedDevicesTest,
        IsDeviceAllowedForUrlContainingEmbeddingOrigin) {
-  std::unique_ptr<base::Value> pref_value = base::JSONReader::ReadDeprecated(
-      kPolicySettingWithUrlContainingEmbeddingOrigin);
+  std::unique_ptr<base::Value> pref_value =
+      ReadJson(kPolicySettingWithUrlContainingEmbeddingOrigin);
 
   SetWebUsbAllowDevicesForUrlsPrefValue(*pref_value);
 
-  auto usb_policy_allowed_devices =
-      std::make_unique<UsbPolicyAllowedDevices>(profile()->GetPrefs());
+  auto usb_policy_allowed_devices = CreateUsbPolicyAllowedDevices();
 
   const auto requesting_origin =
       url::Origin::Create(GURL("https://requesting.com"));
diff --git a/chrome/browser/web_applications/components/web_app_constants.h b/chrome/browser/web_applications/components/web_app_constants.h
index c34fdf2..2337cc35 100644
--- a/chrome/browser/web_applications/components/web_app_constants.h
+++ b/chrome/browser/web_applications/components/web_app_constants.h
@@ -72,7 +72,11 @@
   kIntentToPlayStore = 11,
   // A web app has been disabled by device policy or by other reasons.
   kWebAppDisabled = 12,
-  kMaxValue = kWebAppDisabled
+  // The network request for the install URL was redirected.
+  kInstallURLRedirected = 13,
+  // The network request for the install URL failed or timed out.
+  kInstallURLLoadFailed = 14,
+  kMaxValue = kInstallURLLoadFailed
 };
 
 // Checks if InstallResultCode is not a failure.
diff --git a/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc b/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc
index 49fabc0..1ecb5e3 100644
--- a/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc
+++ b/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc
@@ -855,4 +855,50 @@
   }
 }
 
+TEST_F(PendingAppInstallTaskTest, InstallURLLoadFailed) {
+  struct ResultPair {
+    WebAppUrlLoader::Result loader_result;
+    InstallResultCode install_result;
+  } result_pairs[] = {{WebAppUrlLoader::Result::kRedirectedUrlLoaded,
+                       InstallResultCode::kInstallURLRedirected},
+                      {WebAppUrlLoader::Result::kFailedUnknownReason,
+                       InstallResultCode::kInstallURLLoadFailed},
+                      {WebAppUrlLoader::Result::kFailedPageTookTooLong,
+                       InstallResultCode::kInstallURLLoadFailed}};
+
+  for (const auto& result_pair : result_pairs) {
+    base::RunLoop run_loop;
+
+    ExternalInstallOptions install_options(
+        GURL(), LaunchContainer::kWindow,
+        ExternalInstallSource::kInternalDefault);
+    PendingAppInstallTask install_task(profile(), registrar(), ui_manager(),
+                                       finalizer(), install_options);
+
+    install_task.Install(
+        web_contents(), result_pair.loader_result,
+        base::BindLambdaForTesting([&](PendingAppInstallTask::Result result) {
+          EXPECT_EQ(result.code, result_pair.install_result);
+          run_loop.Quit();
+        }));
+
+    run_loop.Run();
+  }
+}
+
+TEST_F(PendingAppInstallTaskTest, FailedWebContentsDestroyed) {
+  ExternalInstallOptions install_options(
+      GURL(), LaunchContainer::kWindow,
+      ExternalInstallSource::kInternalDefault);
+  PendingAppInstallTask install_task(profile(), registrar(), ui_manager(),
+                                     finalizer(), install_options);
+
+  install_task.Install(
+      web_contents(), WebAppUrlLoader::Result::kFailedWebContentsDestroyed,
+      base::BindLambdaForTesting(
+          [&](PendingAppInstallTask::Result) { NOTREACHED(); }));
+
+  base::RunLoop().RunUntilIdle();
+}
+
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
index 3a72998..ee20fc4 100644
--- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
+++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -228,8 +228,8 @@
 TEST_F(WebAppPolicyManagerTest, TwoForceInstalledApps) {
   // Add two sites, one that opens in a window and one that opens in a tab.
   base::Value list(base::Value::Type::LIST);
-  list.GetList().push_back(GetWindowedItem());
-  list.GetList().push_back(GetTabbedItem());
+  list.Append(GetWindowedItem());
+  list.Append(GetTabbedItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
 
   policy_manager()->Start();
@@ -246,7 +246,7 @@
 
 TEST_F(WebAppPolicyManagerTest, ForceInstallAppWithNoDefaultLaunchContainer) {
   base::Value list(base::Value::Type::LIST);
-  list.GetList().push_back(GetNoContainerItem());
+  list.Append(GetNoContainerItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
 
   policy_manager()->Start();
@@ -263,7 +263,7 @@
 TEST_F(WebAppPolicyManagerTest,
        ForceInstallAppWithDefaultCreateDesktopShorcut) {
   base::Value list(base::Value::Type::LIST);
-  list.GetList().push_back(GetCreateDesktopShorcutDefaultItem());
+  list.Append(GetCreateDesktopShorcutDefaultItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
 
   policy_manager()->Start();
@@ -280,8 +280,8 @@
 
 TEST_F(WebAppPolicyManagerTest, ForceInstallAppWithCreateDesktopShortcut) {
   base::Value list(base::Value::Type::LIST);
-  list.GetList().push_back(GetCreateDesktopShorcutFalseItem());
-  list.GetList().push_back(GetCreateDesktopShorcutTrueItem());
+  list.Append(GetCreateDesktopShorcutFalseItem());
+  list.Append(GetCreateDesktopShorcutTrueItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
 
   policy_manager()->Start();
@@ -300,7 +300,7 @@
 
 TEST_F(WebAppPolicyManagerTest, DynamicRefresh) {
   base::Value first_list(base::Value::Type::LIST);
-  first_list.GetList().push_back(GetWindowedItem());
+  first_list.Append(GetWindowedItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList,
                              std::move(first_list));
 
@@ -315,7 +315,7 @@
   EXPECT_EQ(install_requests, expected_install_options_list);
 
   base::Value second_list(base::Value::Type::LIST);
-  second_list.GetList().push_back(GetTabbedItem());
+  second_list.Append(GetTabbedItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList,
                              std::move(second_list));
 
@@ -338,7 +338,7 @@
 
   // Push a policy with only one of the apps.
   base::Value first_list(base::Value::Type::LIST);
-  first_list.GetList().push_back(GetWindowedItem());
+  first_list.Append(GetWindowedItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList,
                              std::move(first_list));
 
@@ -364,8 +364,8 @@
 
   // Add two sites, one that opens in a window and one that opens in a tab.
   base::Value first_list(base::Value::Type::LIST);
-  first_list.GetList().push_back(GetWindowedItem());
-  first_list.GetList().push_back(GetTabbedItem());
+  first_list.Append(GetWindowedItem());
+  first_list.Append(GetTabbedItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList,
                              std::move(first_list));
   base::RunLoop().RunUntilIdle();
@@ -380,7 +380,7 @@
 
   // Push a new policy without the tabbed site.
   base::Value second_list(base::Value::Type::LIST);
-  second_list.GetList().push_back(GetWindowedItem());
+  second_list.Append(GetWindowedItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList,
                              std::move(second_list));
   base::RunLoop().RunUntilIdle();
@@ -398,7 +398,7 @@
 // Tests that we correctly reinstall a placeholder app.
 TEST_F(WebAppPolicyManagerTest, ReinstallPlaceholderApp) {
   base::Value list(base::Value::Type::LIST);
-  list.GetList().push_back(GetWindowedItem());
+  list.Append(GetWindowedItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
 
   policy_manager()->Start();
@@ -424,7 +424,7 @@
 
 TEST_F(WebAppPolicyManagerTest, TryToInexistentPlaceholderApp) {
   base::Value list(base::Value::Type::LIST);
-  list.GetList().push_back(GetWindowedItem());
+  list.Append(GetWindowedItem());
   profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
 
   policy_manager()->Start();
@@ -449,13 +449,13 @@
   // Add an app.
   {
     base::Value list(base::Value::Type::LIST);
-    list.GetList().push_back(GetWindowedItem());
+    list.Append(GetWindowedItem());
     profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
   }
   // Before it gets installed, set a policy that uninstalls it.
   {
     base::Value list(base::Value::Type::LIST);
-    list.GetList().push_back(GetTabbedItem());
+    list.Append(GetTabbedItem());
     profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
   }
   base::RunLoop().RunUntilIdle();
@@ -485,7 +485,7 @@
   policy_manager()->Start();
   {
     base::Value list(base::Value::Type::LIST);
-    list.GetList().push_back(GetWindowedItem());
+    list.Append(GetWindowedItem());
     profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list));
 
     histograms.ExpectTotalCount(
@@ -501,8 +501,8 @@
   }
   {
     base::Value list(base::Value::Type::LIST);
-    list.GetList().push_back(GetTabbedItem());
-    list.GetList().push_back(GetNoContainerItem());
+    list.Append(GetTabbedItem());
+    list.Append(GetNoContainerItem());
     pending_app_manager()->SetInstallResultCode(
         InstallResultCode::kProfileDestroyed);
 
diff --git a/chrome/browser/web_applications/pending_app_install_task.cc b/chrome/browser/web_applications/pending_app_install_task.cc
index 2027a1f..a6f3b92 100644
--- a/chrome/browser/web_applications/pending_app_install_task.cc
+++ b/chrome/browser/web_applications/pending_app_install_task.cc
@@ -86,10 +86,20 @@
     return;
   }
 
+  // Avoid counting an error if we are shutting down. This matches later
+  // stages of install where if the WebContents is destroyed we return early.
+  if (load_url_result == WebAppUrlLoader::Result::kFailedWebContentsDestroyed)
+    return;
+
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(std::move(result_callback),
-                                Result(InstallResultCode::kFailedUnknownReason,
-                                       base::nullopt)));
+      FROM_HERE,
+      base::BindOnce(
+          std::move(result_callback),
+          Result(
+              load_url_result == WebAppUrlLoader::Result::kRedirectedUrlLoaded
+                  ? InstallResultCode::kInstallURLRedirected
+                  : InstallResultCode::kInstallURLLoadFailed,
+              base::nullopt)));
 }
 
 void PendingAppInstallTask::UninstallPlaceholderApp(
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index ba64f7d..19d73db 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -68,7 +68,7 @@
 const base::Feature kAppServiceIntentHandling{
     "AppServiceIntentHandling", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kAppServiceShelf{"AppServiceShelf",
-                                     base::FEATURE_DISABLED_BY_DEFAULT};
+                                     base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // !defined(OS_ANDROID)
 
 // Enables the built-in DNS resolver.
diff --git a/chrome/common/extensions/docs/templates/intros/certificateProvider.html b/chrome/common/extensions/docs/templates/intros/certificateProvider.html
index ea0e39fd..ff0589b 100644
--- a/chrome/common/extensions/docs/templates/intros/certificateProvider.html
+++ b/chrome/common/extensions/docs/templates/intros/certificateProvider.html
@@ -54,7 +54,7 @@
 The actual sequence of steps can be different. For example, the user will not be
 asked to select a certificate if the enterprise policy to automatically select a
 certificate is used (see
-<a href="https://www.chromium.org/administrators/policy-list-3#AutoSelectCertificateForUrls">AutoSelectCertificateForUrls</a>
+<a href="https://cloud.google.com/docs/chrome-enterprise/policies/?policy=AutoSelectCertificateForUrls">AutoSelectCertificateForUrls</a>
 and
 <a href="https://support.google.com/chrome/a/answer/2657289?hl=en#AutoSelectCertificateForUrls">Chrome policies for users</a>).
 </p>
diff --git a/chrome/common/extensions/docs/templates/intros/webRequest.html b/chrome/common/extensions/docs/templates/intros/webRequest.html
index 8e8b339..389b39d 100644
--- a/chrome/common/extensions/docs/templates/intros/webRequest.html
+++ b/chrome/common/extensions/docs/templates/intros/webRequest.html
@@ -119,12 +119,15 @@
 </p>
 
 <p>
-<span class="availability">Starting from Chrome 79</span>, header modifications
-affect Cross-Origin Resource Sharing (CORS) checks. If modified headers for
-cross-origin requests do not meet the criteria, it will result in sending a CORS
-preflight to ask the server if such headers can be accepted. If you really need
-to modify headers in a way to violate the CORS protocol, you need to specify
-<code>'extraHeaders'</code> in <code>opt_extraInfoSpec</code>.
+<span class="availability">Starting from Chrome 79</span>, request header
+modifications affect Cross-Origin Resource Sharing (CORS) checks. If modified
+headers for cross-origin requests do not meet the criteria, it will result in
+sending a CORS preflight to ask the server if such headers can be accepted.
+If you really need to modify headers in a way to violate the CORS protocol, you
+need to specify <code>'extraHeaders'</code> in <code>opt_extraInfoSpec</code>.
+On the other hand, response header modifications do not work to deceive CORS
+checks. If you need to deceive the CORS protocol, you also need to specify
+<code>'extraHeaders'</code> for the response modifications.
 </p>
 
 <p>
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_background_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_background_unittest.cc
index a036e1b..5009ec25 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_background_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_background_unittest.cc
@@ -91,7 +91,7 @@
   EXPECT_TRUE(BackgroundInfo::HasLazyBackgroundPage(extension.get()));
 
   base::Value permissions(base::Value::Type::LIST);
-  permissions.GetList().push_back(base::Value("webRequest"));
+  permissions.Append(base::Value("webRequest"));
   manifest.SetKey(keys::kPermissions, std::move(permissions));
   LoadAndExpectError(ManifestData(&manifest, ""),
                      errors::kWebRequestConflictsWithLazyBackground);
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
index 6d6241b..4d1d897 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
@@ -125,8 +125,8 @@
   // Create each manifest.
   for (const char* api_name : kPlatformAppExperimentalApis) {
     base::Value permissions(base::Value::Type::LIST);
-    permissions.GetList().push_back(base::Value("experimental"));
-    permissions.GetList().push_back(base::Value(api_name));
+    permissions.Append(base::Value("experimental"));
+    permissions.Append(base::Value(api_name));
     manifest.SetKey("permissions", std::move(permissions));
     manifests.push_back(
         std::make_unique<ManifestData>(manifest.CreateDeepCopy(), ""));
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc
index 193ac81..6b53be3 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc
@@ -31,6 +31,6 @@
   base::Value* permissions =
       manifest.FindKeyOfType("permissions", base::Value::Type::LIST);
   ASSERT_TRUE(permissions);
-  permissions->GetList().emplace_back("not-a-valid-permission");
+  permissions->Append("not-a-valid-permission");
   LoadAndExpectSuccess(ManifestData(std::move(manifest), ""));
 }
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 5343740..6f001b43 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -997,6 +997,11 @@
 // Boolean user profile pref that determines whether to show a banner in browser
 // settings "About Chrome" that links to OS settings "About Chrome OS".
 const char kSettingsShowAboutOSBanner[] = "settings.cros.show_about_os_banner";
+
+// A JSON pref for controlling which USB devices are whitelisted for certain
+// urls to be used via the WebUSB API on the login screen.
+const char kDeviceLoginScreenWebUsbAllowDevicesForUrls[] =
+    "device_login_screen_webusb_allow_devices_for_urls";
 #endif  // defined(OS_CHROMEOS)
 
 // A boolean pref set to true if a Home button to open the Home pages should be
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 4ea8ce8..f883b34 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -317,6 +317,7 @@
 extern const char kSettingsShowBrowserBanner[];
 extern const char kSettingsShowOSBanner[];
 extern const char kSettingsShowAboutOSBanner[];
+extern const char kDeviceLoginScreenWebUsbAllowDevicesForUrls[];
 #endif  // defined(OS_CHROMEOS)
 extern const char kShowHomeButton[];
 extern const char kSpeechRecognitionFilterProfanities[];
diff --git a/chrome/renderer/net/available_offline_content_helper.cc b/chrome/renderer/net/available_offline_content_helper.cc
index 71a035d..a7bd9874 100644
--- a/chrome/renderer/net/available_offline_content_helper.cc
+++ b/chrome/renderer/net/available_offline_content_helper.cc
@@ -71,7 +71,7 @@
     const std::vector<AvailableOfflineContentPtr>& content_list) {
   base::Value value(base::Value::Type::LIST);
   for (const auto& content : content_list) {
-    value.GetList().push_back(AvailableContentToValue(content));
+    value.Append(AvailableContentToValue(content));
   }
   return value;
 }
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc
index 3147d97..a83b272 100644
--- a/chrome/renderer/searchbox/searchbox_extension.cc
+++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -1357,7 +1357,7 @@
       base::Value entry(base::Value::Type::DICTIONARY);
       entry.SetIntKey("offset", classification->offset);
       entry.SetIntKey("style", classification->style);
-      contents_class.GetList().push_back(std::move(entry));
+      contents_class.Append(std::move(entry));
     }
     dict.SetKey("contentsClass", std::move(contents_class));
     dict.SetStringKey("description", match->description);
@@ -1366,7 +1366,7 @@
       base::Value entry(base::Value::Type::DICTIONARY);
       entry.SetIntKey("offset", classification->offset);
       entry.SetIntKey("style", classification->style);
-      description_class.GetList().push_back(std::move(entry));
+      description_class.Append(std::move(entry));
     }
     dict.SetKey("descriptionClass", std::move(description_class));
     dict.SetStringKey("destinationUrl", match->destination_url);
@@ -1376,7 +1376,7 @@
     dict.SetBoolKey("swapContentsAndDescription",
                     match->swap_contents_and_description);
     dict.SetStringKey("type", match->type);
-    list.GetList().push_back(std::move(dict));
+    list.Append(std::move(dict));
   }
   std::string json;
   base::JSONWriter::Write(list, &json);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index edbf1e10..fb9416040 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -5866,8 +5866,6 @@
       "../browser/sync/test/integration/migration_watcher.h",
       "../browser/sync/test/integration/multi_client_status_change_checker.cc",
       "../browser/sync/test/integration/multi_client_status_change_checker.h",
-      "../browser/sync/test/integration/p2p_sync_refresher.cc",
-      "../browser/sync/test/integration/p2p_sync_refresher.h",
       "../browser/sync/test/integration/passwords_helper.cc",
       "../browser/sync/test/integration/passwords_helper.h",
       "../browser/sync/test/integration/preferences_helper.cc",
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index df6d580a..f4262863 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -1095,22 +1095,24 @@
   network_context_ = std::move(network_context);
 }
 
-network::mojom::NetworkContextPtr TestingProfile::CreateNetworkContext(
+mojo::Remote<network::mojom::NetworkContext>
+TestingProfile::CreateNetworkContext(
     bool in_memory,
     const base::FilePath& relative_partition_path) {
   if (network_context_) {
-    network::mojom::NetworkContextPtr network_context_ptr;
+    mojo::Remote<network::mojom::NetworkContext> network_context_remote;
     network_context_bindings_.AddBinding(
-        network_context_.get(), mojo::MakeRequest(&network_context_ptr));
-    return network_context_ptr;
+        network_context_.get(),
+        network_context_remote.BindNewPipeAndPassReceiver());
+    return network_context_remote;
   }
-  network::mojom::NetworkContextPtr network_context;
+  mojo::Remote<network::mojom::NetworkContext> network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       network::mojom::NetworkContextParams::New();
   context_params->user_agent = GetUserAgent();
   context_params->accept_language = "en-us,en";
   content::GetNetworkService()->CreateNetworkContext(
-      MakeRequest(&network_context), std::move(context_params));
+      network_context.BindNewPipeAndPassReceiver(), std::move(context_params));
   return network_context;
 }
 
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index 962255d8..7d163d2 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -354,7 +354,7 @@
   bool IsNewProfile() override;
   void SetExitType(ExitType exit_type) override {}
   ExitType GetLastSessionExitType() override;
-  network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       bool in_memory,
       const base::FilePath& relative_partition_path) override;
 
diff --git a/chrome/test/chromedriver/chrome/cast_tracker_unittest.cc b/chrome/test/chromedriver/chrome/cast_tracker_unittest.cc
index b88437a..b9248ce 100644
--- a/chrome/test/chromedriver/chrome/cast_tracker_unittest.cc
+++ b/chrome/test/chromedriver/chrome/cast_tracker_unittest.cc
@@ -54,8 +54,8 @@
   EXPECT_EQ(0u, cast_tracker_->sinks().GetList().size());
 
   base::Value sinks(base::Value::Type::LIST);
-  sinks.GetList().emplace_back(CreateSink("sink1", "1"));
-  sinks.GetList().emplace_back(CreateSink("sink2", "2"));
+  sinks.Append(CreateSink("sink1", "1"));
+  sinks.Append(CreateSink("sink2", "2"));
   params.SetKey("sinks", std::move(sinks));
   cast_tracker_->OnEvent(&devtools_client_, "Cast.sinksUpdated", params);
   EXPECT_EQ(2u, cast_tracker_->sinks().GetList().size());
diff --git a/chrome/test/chromedriver/performance_logger_unittest.cc b/chrome/test/chromedriver/performance_logger_unittest.cc
index 40ec2847..adc959a 100644
--- a/chrome/test/chromedriver/performance_logger_unittest.cc
+++ b/chrome/test/chromedriver/performance_logger_unittest.cc
@@ -334,10 +334,10 @@
   auto trace_events = std::make_unique<base::ListValue>();
   auto event1 = std::make_unique<base::DictionaryValue>();
   event1->SetString("cat", "foo");
-  trace_events->GetList().push_back(event1->Clone());
+  trace_events->Append(event1->Clone());
   auto event2 = std::make_unique<base::DictionaryValue>();
   event2->SetString("cat", "bar");
-  trace_events->GetList().push_back(event2->Clone());
+  trace_events->Append(event2->Clone());
   params.Set("value", std::move(trace_events));
   ASSERT_EQ(kOk, client.TriggerEvent("Tracing.dataCollected", params).code());
 
diff --git a/chrome/test/data/extensions/api_test/webrequest/cors/fetch.html b/chrome/test/data/extensions/api_test/webrequest/cors/fetch.html
index 7c063db..ac81c202 100644
--- a/chrome/test/data/extensions/api_test/webrequest/cors/fetch.html
+++ b/chrome/test/data/extensions/api_test/webrequest/cors/fetch.html
@@ -6,8 +6,8 @@
 <script>
 const hostname = 'cors.example.com';
 const origin = location.protocol + '//' + hostname + ':' + location.port;
-const path = '/extensions/api_test/webrequest/cors/accept';
-const url = origin + path;
+const path = location.search.substr('?path='.length);
+const url = origin + '/extensions/api_test/webrequest/cors/' + path;
 
 fetch(url);
 </script>
diff --git a/chrome/test/data/extensions/api_test/webrequest/cors/reject b/chrome/test/data/extensions/api_test/webrequest/cors/reject
new file mode 100644
index 0000000..a862a62
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webrequest/cors/reject
@@ -0,0 +1 @@
+ERR
diff --git a/chrome/test/data/extensions/api_test/webrequest/cors/reject.mock-http-headers b/chrome/test/data/extensions/api_test/webrequest/cors/reject.mock-http-headers
new file mode 100644
index 0000000..5c695b91
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webrequest/cors/reject.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.1 200 OK
+Content-Type: text/plain
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_cors.js b/chrome/test/data/extensions/api_test/webrequest/test_cors.js
index 8de717f..64805b3 100644
--- a/chrome/test/data/extensions/api_test/webrequest/test_cors.js
+++ b/chrome/test/data/extensions/api_test/webrequest/test_cors.js
@@ -35,13 +35,13 @@
       onCompletedListener, {urls: [listeningUrlPattern]});
 }
 
-function registerHeaderInjectionListeners(extraInfoSpec) {
+function registerRequestHeaderInjectionListeners(extraInfoSpec) {
   const beforeSendHeadersListener = callbackPass(details => {
     details.requestHeaders.push({name: 'x-foo', value: 'trigger-preflight'});
-    return { requestHeaders: details.requestHeaders };
+    return {requestHeaders: details.requestHeaders};
   });
   chrome.webRequest.onBeforeSendHeaders.addListener(
-    beforeSendHeadersListener, {urls: [listeningUrlPattern]}, extraInfoSpec);
+      beforeSendHeadersListener, {urls: [listeningUrlPattern]}, extraInfoSpec);
 
   // If the 'x-foo' header is injected by |beforeSendHeadersListener| without
   // 'extraHeaders' and with OOR-CORS being enabled, it triggers CORS
@@ -66,6 +66,32 @@
   event.addListener(
       onCompletedOrErrorOccurredListener, {urls: [listeningUrlPattern]});
 }
+function registerResponseHeaderInjectionListeners(extraInfoSpec) {
+  const headersReceivedListener = details => {
+    details.responseHeaders.push(
+        {name: 'Access-Control-Allow-Origin', value: '*'});
+    return { responseHeaders: details.responseHeaders };
+  };
+  chrome.webRequest.onHeadersReceived.addListener(
+      headersReceivedListener, {urls: [listeningUrlPattern]}, extraInfoSpec);
+
+  // If the 'extraHeaders' is not specified and OOR-CORS is enabled, Chrome
+  // detects CORS failures before |headerReceivedListener| is called and injects
+  // fake headers to deceive the CORS checks.
+  const canInjectFakeCorsResponse =
+      extraInfoSpec.includes('extraHeaders') || getCorsMode() == 'blink';
+
+  const event = canInjectFakeCorsResponse ? chrome.webRequest.onCompleted :
+                                            chrome.webRequest.onErrorOccurred;
+
+  // Wait for the CORS request from the fetch.html to complete.
+  const onCompletedOrErrorOccurredListener = callbackPass(details => {
+    chrome.webRequest.onHeadersReceived.removeListener(headersReceivedListener);
+    event.removeListener(onCompletedOrErrorOccurredListener);
+  });
+  event.addListener(
+      onCompletedOrErrorOccurredListener, {urls: [listeningUrlPattern]});
+}
 
 runTests([
   function testOriginHeader() {
@@ -80,22 +106,38 @@
     registerOriginListeners(['origin'], [], ['requestHeaders', 'extraHeaders']);
 
     // Wait for the navigation to complete.
-    navigateAndWait(
-        getServerURL('extensions/api_test/webrequest/cors/fetch.html'));
+    navigateAndWait(getServerURL(
+        'extensions/api_test/webrequest/cors/fetch.html?path=accept'));
   },
   function testCorsSensitiveHeaderInjectionWithoutExtraHeaders() {
-    registerHeaderInjectionListeners(['blocking', 'requestHeaders']);
+    registerRequestHeaderInjectionListeners(['blocking', 'requestHeaders']);
 
     // Wait for the navigation to complete.
-    navigateAndWait(
-        getServerURL('extensions/api_test/webrequest/cors/fetch.html'));
+    navigateAndWait(getServerURL(
+        'extensions/api_test/webrequest/cors/fetch.html?path=accept'));
   },
   function testCorsSensitiveHeaderInjectionWithExtraHeaders() {
-    registerHeaderInjectionListeners(
+    registerRequestHeaderInjectionListeners(
         ['blocking', 'requestHeaders', 'extraHeaders']);
 
     // Wait for the navigation to complete.
-    navigateAndWait(
-        getServerURL('extensions/api_test/webrequest/cors/fetch.html'));
+    navigateAndWait(getServerURL(
+        'extensions/api_test/webrequest/cors/fetch.html?path=accept'));
+  },
+  function testCorsResponseHeaderInjectionWithoutExtraHeaders() {
+    registerResponseHeaderInjectionListeners(
+        ['blocking', 'responseHeaders']);
+
+    // Wait for the navigation to complete.
+    navigateAndWait(getServerURL(
+        'extensions/api_test/webrequest/cors/fetch.html?path=reject'));
+  },
+  function testCorsResponseHeaderInjectionWithExtraHeaders() {
+    registerResponseHeaderInjectionListeners(
+        ['blocking', 'responseHeaders', 'extraHeaders']);
+
+    // Wait for the navigation to complete.
+    navigateAndWait(getServerURL(
+        'extensions/api_test/webrequest/cors/fetch.html?path=reject'));
   },
 ]);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index bcfaea3..dff752f 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2040,6 +2040,19 @@
     ]
   },
 
+  "DeviceLoginScreenWebUsbAllowDevicesForUrls": {
+    "os": ["chromeos"],
+    "test_policy": { "DeviceLoginScreenWebUsbAllowDevicesForUrls": [{
+      "devices": [{"vendor_id": 1234, "product_id": 5678}],
+      "urls": ["https://google.com", "https://requesting.com,https://embedded.com"]
+    }]},
+    "pref_mappings": [
+      { "pref": "device_login_screen_webusb_allow_devices_for_urls",
+        "local_state": true
+      }
+    ]
+  },
+
   "WebUsbAskForUrls": {
     "os": ["win", "linux", "mac", "chromeos", "android"],
     "test_policy": { "WebUsbAskForUrls": ["[*.]google.com"] },
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index 517c43a..6012e74 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -44,6 +44,7 @@
 #include "extensions/test/extension_test_message_listener.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/net_errors.h"
@@ -841,9 +842,9 @@
 // pipe makes sure that everything happens asynchronously through a pipe.
 #define RUN_TCP_FAILURE_TEST(test_name, failure_type)                         \
   do {                                                                        \
-    network::mojom::NetworkContextPtr network_context_proxy;                  \
+    mojo::Remote<network::mojom::NetworkContext> network_context_proxy;       \
     MockNetworkContext network_context(                                       \
-        failure_type, mojo::MakeRequest(&network_context_proxy));             \
+        failure_type, network_context_proxy.BindNewPipeAndPassReceiver());    \
     ppapi::SetPepperTCPNetworkContextForTesting(network_context_proxy.get()); \
     RunTestViaHTTP(LIST_TEST(test_name));                                     \
     ppapi::SetPepperTCPNetworkContextForTesting(nullptr);                     \
diff --git a/chromecast/browser/application_media_capabilities.cc b/chromecast/browser/application_media_capabilities.cc
index 443baa0..f8ed2de1 100644
--- a/chromecast/browser/application_media_capabilities.cc
+++ b/chromecast/browser/application_media_capabilities.cc
@@ -16,25 +16,26 @@
 
 ApplicationMediaCapabilities::~ApplicationMediaCapabilities() = default;
 
-void ApplicationMediaCapabilities::AddBinding(
-    mojom::ApplicationMediaCapabilitiesRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+void ApplicationMediaCapabilities::AddReceiver(
+    mojo::PendingReceiver<mojom::ApplicationMediaCapabilities> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 void ApplicationMediaCapabilities::SetSupportedBitstreamAudioCodecs(
     int codecs) {
   supported_bitstream_audio_codecs_ = codecs;
-  observers_.ForAllPtrs(
-      [codecs](mojom::ApplicationMediaCapabilitiesObserver* observer) {
-        observer->OnSupportedBitstreamAudioCodecsChanged(codecs);
-      });
+  for (auto& observer : observers_)
+    observer->OnSupportedBitstreamAudioCodecsChanged(codecs);
 }
 
 void ApplicationMediaCapabilities::AddObserver(
-    mojom::ApplicationMediaCapabilitiesObserverPtr observer) {
+    mojo::PendingRemote<mojom::ApplicationMediaCapabilitiesObserver>
+        observer_remote) {
+  mojo::Remote<mojom::ApplicationMediaCapabilitiesObserver> observer(
+      std::move(observer_remote));
   observer->OnSupportedBitstreamAudioCodecsChanged(
       supported_bitstream_audio_codecs_);
-  observers_.AddPtr(std::move(observer));
+  observers_.Add(std::move(observer));
 }
 
 }  // namespace shell
diff --git a/chromecast/browser/application_media_capabilities.h b/chromecast/browser/application_media_capabilities.h
index b19f838..bc5a6c2 100644
--- a/chromecast/browser/application_media_capabilities.h
+++ b/chromecast/browser/application_media_capabilities.h
@@ -7,8 +7,9 @@
 
 #include "base/macros.h"
 #include "chromecast/common/mojom/application_media_capabilities.mojom.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
 
 namespace content {
 class RenderFrameHost;
@@ -23,17 +24,19 @@
   ApplicationMediaCapabilities();
   ~ApplicationMediaCapabilities() override;
 
-  void AddBinding(mojom::ApplicationMediaCapabilitiesRequest request);
+  void AddReceiver(
+      mojo::PendingReceiver<mojom::ApplicationMediaCapabilities> receiver);
 
   void SetSupportedBitstreamAudioCodecs(int codecs);
 
  private:
   // mojom::ApplicationMediaCapabilities implementation:
   void AddObserver(
-      mojom::ApplicationMediaCapabilitiesObserverPtr observer) override;
+      mojo::PendingRemote<mojom::ApplicationMediaCapabilitiesObserver>
+          observer_remote) override;
 
-  mojo::BindingSet<mojom::ApplicationMediaCapabilities> bindings_;
-  mojo::InterfacePtrSet<mojom::ApplicationMediaCapabilitiesObserver> observers_;
+  mojo::ReceiverSet<mojom::ApplicationMediaCapabilities> receivers_;
+  mojo::RemoteSet<mojom::ApplicationMediaCapabilitiesObserver> observers_;
   int supported_bitstream_audio_codecs_;
 
   DISALLOW_COPY_AND_ASSIGN(ApplicationMediaCapabilities);
diff --git a/chromecast/browser/bluetooth/cast_bluetooth_chooser.cc b/chromecast/browser/bluetooth/cast_bluetooth_chooser.cc
index dd41c5e..dd6d4013 100644
--- a/chromecast/browser/bluetooth/cast_bluetooth_chooser.cc
+++ b/chromecast/browser/bluetooth/cast_bluetooth_chooser.cc
@@ -4,20 +4,20 @@
 
 #include "chromecast/browser/bluetooth/cast_bluetooth_chooser.h"
 #include "base/bind.h"
+#include "mojo/public/cpp/bindings/remote.h"
 
 namespace chromecast {
 
 CastBluetoothChooser::CastBluetoothChooser(
     content::BluetoothChooser::EventHandler event_handler,
-    mojom::BluetoothDeviceAccessProviderPtr provider)
-    : event_handler_(std::move(event_handler)), binding_(this) {
+    mojo::PendingRemote<mojom::BluetoothDeviceAccessProvider> pending_provider)
+    : event_handler_(std::move(event_handler)) {
   DCHECK(event_handler_);
-
-  mojom::BluetoothDeviceAccessProviderClientPtr client;
-  binding_.Bind(mojo::MakeRequest(&client));
-  binding_.set_connection_error_handler(base::BindOnce(
+  mojo::Remote<mojom::BluetoothDeviceAccessProvider> provider(
+      std::move(pending_provider));
+  provider->RequestDeviceAccess(receiver_.BindNewPipeAndPassRemote());
+  receiver_.set_disconnect_handler(base::BindOnce(
       &CastBluetoothChooser::OnClientConnectionError, base::Unretained(this)));
-  provider->RequestDeviceAccess(std::move(client));
 }
 
 CastBluetoothChooser::~CastBluetoothChooser() = default;
@@ -31,7 +31,7 @@
   }
 
   if (available_devices_.find(address) != available_devices_.end()) {
-    RunEventHandlerAndResetBinding(Event::SELECTED, address);
+    RunEventHandlerAndResetReceiver(Event::SELECTED, address);
     return;
   }
   approved_devices_.insert(address);
@@ -42,8 +42,8 @@
 
   all_devices_approved_ = true;
   if (!available_devices_.empty()) {
-    RunEventHandlerAndResetBinding(Event::SELECTED,
-                                   *available_devices_.begin());
+    RunEventHandlerAndResetReceiver(Event::SELECTED,
+                                    *available_devices_.begin());
   }
 }
 
@@ -58,18 +58,18 @@
   // Note: |device_id| is just a canonical Bluetooth address.
   if (all_devices_approved_ ||
       approved_devices_.find(device_id) != approved_devices_.end()) {
-    RunEventHandlerAndResetBinding(Event::SELECTED, device_id);
+    RunEventHandlerAndResetReceiver(Event::SELECTED, device_id);
     return;
   }
   available_devices_.insert(device_id);
 }
 
-void CastBluetoothChooser::RunEventHandlerAndResetBinding(
+void CastBluetoothChooser::RunEventHandlerAndResetReceiver(
     content::BluetoothChooser::Event event,
     std::string address) {
   DCHECK(event_handler_);
   std::move(event_handler_).Run(event, std::move(address));
-  binding_.Close();
+  receiver_.reset();
 }
 
 void CastBluetoothChooser::OnClientConnectionError() {
@@ -77,7 +77,7 @@
   // tear down the client immediately. In this case, do not run the event
   // handler, as we may have not had the opportunity to select a device.
   if (!all_devices_approved_ && event_handler_) {
-    RunEventHandlerAndResetBinding(Event::CANCELLED, "");
+    RunEventHandlerAndResetReceiver(Event::CANCELLED, "");
   }
 }
 
diff --git a/chromecast/browser/bluetooth/cast_bluetooth_chooser.h b/chromecast/browser/bluetooth/cast_bluetooth_chooser.h
index 60cbd02..97992b2 100644
--- a/chromecast/browser/bluetooth/cast_bluetooth_chooser.h
+++ b/chromecast/browser/bluetooth/cast_bluetooth_chooser.h
@@ -10,8 +10,8 @@
 
 #include "chromecast/browser/bluetooth/public/mojom/web_bluetooth.mojom.h"
 #include "content/public/browser/bluetooth_chooser.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 
 namespace chromecast {
 
@@ -27,7 +27,8 @@
   // the |provider| destroys the connection to this client. |this| may destroy
   // |provider| immediately after requesting access.
   CastBluetoothChooser(content::BluetoothChooser::EventHandler event_handler,
-                       mojom::BluetoothDeviceAccessProviderPtr provider);
+                       mojo::PendingRemote<mojom::BluetoothDeviceAccessProvider>
+                           pending_provider);
   ~CastBluetoothChooser() override;
 
  private:
@@ -43,16 +44,16 @@
                          bool is_paired,
                          int signal_strength_level) override;
 
-  // Runs the event_handler and resets the client binding. After this is called,
-  // this class should not be used.
-  void RunEventHandlerAndResetBinding(content::BluetoothChooser::Event event,
-                                      std::string address);
+  // Runs the event_handler and resets the client receiver. After this is
+  // called, this class should not be used.
+  void RunEventHandlerAndResetReceiver(content::BluetoothChooser::Event event,
+                                       std::string address);
 
-  // Called when the remote connection held by |binding_| is torn down.
+  // Called when the remote connection held by |receiver_| is torn down.
   void OnClientConnectionError();
 
   content::BluetoothChooser::EventHandler event_handler_;
-  mojo::Binding<mojom::BluetoothDeviceAccessProviderClient> binding_;
+  mojo::Receiver<mojom::BluetoothDeviceAccessProviderClient> receiver_{this};
   std::unordered_set<std::string> available_devices_;
   std::unordered_set<std::string> approved_devices_;
   bool all_devices_approved_ = false;
diff --git a/chromecast/browser/bluetooth/cast_bluetooth_chooser_unittest.cc b/chromecast/browser/bluetooth/cast_bluetooth_chooser_unittest.cc
index ac25d3e..6eae56e9 100644
--- a/chromecast/browser/bluetooth/cast_bluetooth_chooser_unittest.cc
+++ b/chromecast/browser/bluetooth/cast_bluetooth_chooser_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -19,22 +20,26 @@
 
   // mojom::BluetoothDeviceAccessProvider implementation:
   void RequestDeviceAccess(
-      mojom::BluetoothDeviceAccessProviderClientPtr client) override {
+      mojo::PendingRemote<mojom::BluetoothDeviceAccessProviderClient> client)
+      override {
     DCHECK(!client_);
-    client.set_connection_error_handler(connection_closed_.Get());
+    client_.Bind(std::move(client));
+    client_.set_disconnect_handler(connection_closed_.Get());
     for (const auto& address : approved_devices_)
-      client->GrantAccess(address);
-    client_ = std::move(client);
+      client_->GrantAccess(address);
   }
 
-  mojom::BluetoothDeviceAccessProviderClientPtr& client() { return client_; }
+  mojom::BluetoothDeviceAccessProviderClient* client() {
+    return client_ ? client_.get() : nullptr;
+  }
+  void reset_client() { return client_.reset(); }
   base::MockCallback<base::OnceClosure>& connection_closed() {
     return connection_closed_;
   }
   std::vector<std::string>& approved_devices() { return approved_devices_; }
 
  private:
-  mojom::BluetoothDeviceAccessProviderClientPtr client_;
+  mojo::Remote<mojom::BluetoothDeviceAccessProviderClient> client_;
   base::MockCallback<base::OnceClosure> connection_closed_;
   std::vector<std::string> approved_devices_;
 
@@ -47,11 +52,9 @@
 
 class CastBluetoothChooserTest : public testing::Test {
  public:
-  CastBluetoothChooserTest() : provider_binding_(&provider_) {
-    mojom::BluetoothDeviceAccessProviderPtr provider;
-    provider_binding_.Bind(mojo::MakeRequest(&provider));
+  CastBluetoothChooserTest() : provider_receiver_(&provider_) {
     cast_bluetooth_chooser_ = std::make_unique<CastBluetoothChooser>(
-        handler_.Get(), std::move(provider));
+        handler_.Get(), provider_receiver_.BindNewPipeAndPassRemote());
     task_environment_.RunUntilIdle();
   }
 
@@ -71,7 +74,7 @@
 
  private:
   SimpleDeviceAccessProvider provider_;
-  mojo::Binding<mojom::BluetoothDeviceAccessProvider> provider_binding_;
+  mojo::Receiver<mojom::BluetoothDeviceAccessProvider> provider_receiver_;
   std::unique_ptr<CastBluetoothChooser> cast_bluetooth_chooser_;
 
   DISALLOW_COPY_AND_ASSIGN(CastBluetoothChooserTest);
@@ -152,7 +155,7 @@
   // Tear down the client. Now that it has granted access to the client, it does
   // not need to keep a reference to it. However, the chooser should stay alive
   // and wait for devices to be made available.
-  provider().client().reset();
+  provider().reset_client();
   EXPECT_FALSE(provider().client());
   task_environment_.RunUntilIdle();
 
@@ -171,7 +174,7 @@
   // Tear the client down before any access is granted. |handler| should run,
   // but with Event::CANCELLED.
   EXPECT_CALL(handler_, Run(content::BluetoothChooser::Event::CANCELLED, ""));
-  provider().client().reset();
+  provider().reset_client();
   EXPECT_FALSE(provider().client());
   task_environment_.RunUntilIdle();
 }
diff --git a/chromecast/browser/bluetooth/public/mojom/web_bluetooth.mojom b/chromecast/browser/bluetooth/public/mojom/web_bluetooth.mojom
index 8270612..1d8d6ce 100644
--- a/chromecast/browser/bluetooth/public/mojom/web_bluetooth.mojom
+++ b/chromecast/browser/bluetooth/public/mojom/web_bluetooth.mojom
@@ -10,7 +10,8 @@
 // devices.
 interface BluetoothDeviceAccessProvider {
   // Request that the host begin granting |client| access to approved devices.
-  RequestDeviceAccess(BluetoothDeviceAccessProviderClient client);
+  RequestDeviceAccess(
+      pending_remote<BluetoothDeviceAccessProviderClient> client);
 };
 
 // The client for BluetoothDeviceAccessProvider, provided by the Activity,
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 6dc5d3fb..577ba68 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -737,7 +737,7 @@
     blink::AssociatedInterfaceRegistry* associated_registry,
     content::RenderProcessHost* render_process_host) {
   registry->AddInterface(
-      base::Bind(&media::MediaCapsImpl::AddBinding,
+      base::Bind(&media::MediaCapsImpl::AddReceiver,
                  base::Unretained(cast_browser_main_parts_->media_caps())),
       base::ThreadTaskRunnerHandle::Get());
 
@@ -995,7 +995,7 @@
   cast_network_contexts_->OnNetworkServiceCreated(network_service);
 }
 
-network::mojom::NetworkContextPtr
+mojo::Remote<network::mojom::NetworkContext>
 CastContentBrowserClient::CreateNetworkContext(
     content::BrowserContext* context,
     bool in_memory,
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index 562ee8d..e5acf04 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -213,7 +213,7 @@
       NonNetworkURLLoaderFactoryMap* factories) override;
   void OnNetworkServiceCreated(
       network::mojom::NetworkService* network_service) override;
-  network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       content::BrowserContext* context,
       bool in_memory,
       const base::FilePath& relative_partition_path) override;
diff --git a/chromecast/browser/cast_network_contexts.cc b/chromecast/browser/cast_network_contexts.cc
index f9e9f7f..3f74108 100644
--- a/chromecast/browser/cast_network_contexts.cc
+++ b/chromecast/browser/cast_network_contexts.cc
@@ -137,13 +137,14 @@
   return system_shared_url_loader_factory_;
 }
 
-network::mojom::NetworkContextPtr CastNetworkContexts::CreateNetworkContext(
+mojo::Remote<network::mojom::NetworkContext>
+CastNetworkContexts::CreateNetworkContext(
     content::BrowserContext* context,
     bool in_memory,
     const base::FilePath& relative_partition_path) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  network::mojom::NetworkContextPtr network_context;
+  mojo::Remote<network::mojom::NetworkContext> network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       CreateDefaultNetworkContextParams();
 
@@ -153,7 +154,7 @@
   context_params->accept_language = "en-us,en";
 
   content::GetNetworkService()->CreateNetworkContext(
-      MakeRequest(&network_context), std::move(context_params));
+      network_context.BindNewPipeAndPassReceiver(), std::move(context_params));
   return network_context;
 }
 
diff --git a/chromecast/browser/cast_network_contexts.h b/chromecast/browser/cast_network_contexts.h
index 2f356f1..2077fc00 100644
--- a/chromecast/browser/cast_network_contexts.h
+++ b/chromecast/browser/cast_network_contexts.h
@@ -13,6 +13,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/proxy_resolution/proxy_config_service.h"
 #include "services/network/public/mojom/network_service.mojom.h"
 #include "services/network/public/mojom/proxy_config.mojom.h"
@@ -70,7 +71,7 @@
   // system NetworkContext, if the network service is enabled.
   void OnNetworkServiceCreated(network::mojom::NetworkService* network_service);
 
-  network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       content::BrowserContext* context,
       bool in_memory,
       const base::FilePath& relative_partition_path);
@@ -131,4 +132,4 @@
 }  // namespace shell
 }  // namespace chromecast
 
-#endif  // CHROMECAST_BROWSER_URL_REQUEST_CONTEXT_FACTORY_H_
+#endif  // CHROMECAST_BROWSER_CAST_NETWORK_CONTEXTS_H_
diff --git a/chromecast/browser/media/media_caps_impl.cc b/chromecast/browser/media/media_caps_impl.cc
index d5df37c..a4add26 100644
--- a/chromecast/browser/media/media_caps_impl.cc
+++ b/chromecast/browser/media/media_caps_impl.cc
@@ -8,6 +8,7 @@
 #include "chromecast/browser/media/supported_codec_finder.h"
 #include "chromecast/media/base/media_caps.h"
 #include "chromecast/public/media/decoder_config.h"
+#include "mojo/public/cpp/bindings/remote.h"
 
 namespace chromecast {
 namespace media {
@@ -38,17 +39,15 @@
   supported_codec_finder.FindSupportedCodecProfileLevels(this);
 }
 
-void MediaCapsImpl::AddBinding(
-    mojom::MediaCapsRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+void MediaCapsImpl::AddReceiver(
+    mojo::PendingReceiver<mojom::MediaCaps> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 void MediaCapsImpl::ScreenResolutionChanged(unsigned width, unsigned height) {
   screen_resolution_ = gfx::Size(width, height);
-
-  observers_.ForAllPtrs([width, height](mojom::MediaCapsObserver* observer) {
+  for (auto& observer : observers_)
     observer->ScreenResolutionChanged(width, height);
-  });
 }
 
 void MediaCapsImpl::ScreenInfoChanged(int hdcp_version,
@@ -66,30 +65,28 @@
   current_mode_supports_hdr_ = current_mode_supports_hdr;
   current_mode_supports_dv_ = current_mode_supports_dv;
 
-  observers_.ForAllPtrs([hdcp_version, supported_eotfs, dolby_vision_flags,
-                         screen_width_mm, screen_height_mm,
-                         current_mode_supports_hdr, current_mode_supports_dv](
-      mojom::MediaCapsObserver* observer) {
+  for (auto& observer : observers_) {
     observer->ScreenInfoChanged(hdcp_version, supported_eotfs,
                                 dolby_vision_flags, screen_width_mm,
                                 screen_height_mm, current_mode_supports_hdr,
                                 current_mode_supports_dv);
-  });
+  }
 }
 
 void MediaCapsImpl::AddSupportedCodecProfileLevel(
     const CodecProfileLevel& codec_profile_level) {
   codec_profile_levels_.push_back(codec_profile_level);
-  observers_.ForAllPtrs(
-      [&codec_profile_level](mojom::MediaCapsObserver* observer) {
-        mojom::CodecProfileLevelPtr mojo_codec_profile_level(
-            ConvertCodecProfileLevelToMojo(codec_profile_level));
-        observer->AddSupportedCodecProfileLevel(
-            std::move(mojo_codec_profile_level));
-      });
+  for (auto& observer : observers_) {
+    mojom::CodecProfileLevelPtr mojo_codec_profile_level(
+        ConvertCodecProfileLevelToMojo(codec_profile_level));
+    observer->AddSupportedCodecProfileLevel(
+        std::move(mojo_codec_profile_level));
+  }
 }
 
-void MediaCapsImpl::AddObserver(mojom::MediaCapsObserverPtr observer) {
+void MediaCapsImpl::AddObserver(
+    mojo::PendingRemote<mojom::MediaCapsObserver> observer_remote) {
+  mojo::Remote<mojom::MediaCapsObserver> observer(std::move(observer_remote));
   observer->ScreenResolutionChanged(screen_resolution_.width(),
                                     screen_resolution_.height());
   observer->ScreenInfoChanged(hdcp_version_, supported_eotfs_,
@@ -102,7 +99,7 @@
     observer->AddSupportedCodecProfileLevel(
         ConvertCodecProfileLevelToMojo(codec_profile_level));
   }
-  observers_.AddPtr(std::move(observer));
+  observers_.Add(std::move(observer));
 }
 
 }  // namespace media
diff --git a/chromecast/browser/media/media_caps_impl.h b/chromecast/browser/media/media_caps_impl.h
index 5ba384c..9bb82135 100644
--- a/chromecast/browser/media/media_caps_impl.h
+++ b/chromecast/browser/media/media_caps_impl.h
@@ -9,8 +9,9 @@
 
 #include "base/macros.h"
 #include "chromecast/common/mojom/media_caps.mojom.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace chromecast {
@@ -24,7 +25,7 @@
   ~MediaCapsImpl() override;
 
   void Initialize();
-  void AddBinding(mojom::MediaCapsRequest request);
+  void AddReceiver(mojo::PendingReceiver<mojom::MediaCaps> receiver);
 
   void ScreenResolutionChanged(unsigned width, unsigned height);
   void ScreenInfoChanged(int hdcp_version,
@@ -39,7 +40,8 @@
 
  private:
   // chromecast::mojom::MediaCaps implementation.
-  void AddObserver(mojom::MediaCapsObserverPtr observer) override;
+  void AddObserver(
+      mojo::PendingRemote<mojom::MediaCapsObserver> observer) override;
 
   int hdcp_version_;
   int supported_eotfs_;
@@ -50,8 +52,8 @@
   bool current_mode_supports_dv_;
   gfx::Size screen_resolution_;
   std::vector<CodecProfileLevel> codec_profile_levels_;
-  mojo::InterfacePtrSet<mojom::MediaCapsObserver> observers_;
-  mojo::BindingSet<mojom::MediaCaps> bindings_;
+  mojo::RemoteSet<mojom::MediaCapsObserver> observers_;
+  mojo::ReceiverSet<mojom::MediaCaps> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(MediaCapsImpl);
 };
diff --git a/chromecast/browser/memory_pressure_controller_impl.cc b/chromecast/browser/memory_pressure_controller_impl.cc
index 76505931..b093b53 100644
--- a/chromecast/browser/memory_pressure_controller_impl.cc
+++ b/chromecast/browser/memory_pressure_controller_impl.cc
@@ -24,14 +24,13 @@
 
 void MemoryPressureControllerImpl::OnMemoryPressure(
     base::MemoryPressureListener::MemoryPressureLevel level) {
-  observers_.ForAllPtrs([level](mojom::MemoryPressureObserver* observer) {
+  for (auto& observer : observers_)
     observer->MemoryPressureLevelChanged(level);
-  });
 }
 
 void MemoryPressureControllerImpl::AddObserver(
-    mojom::MemoryPressureObserverPtr observer) {
-  observers_.AddPtr(std::move(observer));
+    mojo::PendingRemote<mojom::MemoryPressureObserver> observer) {
+  observers_.Add(std::move(observer));
 }
 
 }  // namespace chromecast
diff --git a/chromecast/browser/memory_pressure_controller_impl.h b/chromecast/browser/memory_pressure_controller_impl.h
index bfeeb22..fd530fd 100644
--- a/chromecast/browser/memory_pressure_controller_impl.h
+++ b/chromecast/browser/memory_pressure_controller_impl.h
@@ -9,7 +9,8 @@
 #include "base/memory/memory_pressure_listener.h"
 #include "chromecast/common/mojom/memory_pressure.mojom.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
 
 namespace chromecast {
 
@@ -22,12 +23,13 @@
 
  private:
   // chromecast::mojom::MemoryPressure implementation.
-  void AddObserver(mojom::MemoryPressureObserverPtr observer) override;
+  void AddObserver(
+      mojo::PendingRemote<mojom::MemoryPressureObserver> observer) override;
 
   void OnMemoryPressure(
       base::MemoryPressureListener::MemoryPressureLevel level);
 
-  mojo::InterfacePtrSet<mojom::MemoryPressureObserver> observers_;
+  mojo::RemoteSet<mojom::MemoryPressureObserver> observers_;
   mojo::BindingSet<mojom::MemoryPressureController> bindings_;
 
   std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
diff --git a/chromecast/common/mojom/application_media_capabilities.mojom b/chromecast/common/mojom/application_media_capabilities.mojom
index 10f0cdcf..83634afc 100644
--- a/chromecast/common/mojom/application_media_capabilities.mojom
+++ b/chromecast/common/mojom/application_media_capabilities.mojom
@@ -12,5 +12,5 @@
 
 // Media capabilities for an individual application.
 interface ApplicationMediaCapabilities {
-  AddObserver(ApplicationMediaCapabilitiesObserver observer);
+  AddObserver(pending_remote<ApplicationMediaCapabilitiesObserver> observer);
 };
diff --git a/chromecast/common/mojom/media_caps.mojom b/chromecast/common/mojom/media_caps.mojom
index 2c33389..5bb92873 100644
--- a/chromecast/common/mojom/media_caps.mojom
+++ b/chromecast/common/mojom/media_caps.mojom
@@ -12,7 +12,7 @@
 
 // Media capabilities that apply to all applications.
 interface MediaCaps {
-  AddObserver(MediaCapsObserver observer);
+  AddObserver(pending_remote<MediaCapsObserver> observer);
 };
 
 // Observes changes in media capabilities that apply to all applications.
diff --git a/chromecast/common/mojom/memory_pressure.mojom b/chromecast/common/mojom/memory_pressure.mojom
index 3e7face..30554488 100644
--- a/chromecast/common/mojom/memory_pressure.mojom
+++ b/chromecast/common/mojom/memory_pressure.mojom
@@ -5,7 +5,7 @@
 module chromecast.mojom;
 
 interface MemoryPressureController {
-  AddObserver(MemoryPressureObserver observer);
+  AddObserver(pending_remote<MemoryPressureObserver> observer);
 };
 
 interface MemoryPressureObserver {
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index 24d5cff..674d34a 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -29,6 +29,7 @@
 #include "media/base/audio_parameters.h"
 #include "media/base/media.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/blink/public/platform/web_runtime_features.h"
 #include "third_party/blink/public/web/web_frame_widget.h"
@@ -76,7 +77,6 @@
 CastContentRendererClient::CastContentRendererClient()
     : supported_profiles_(
           std::make_unique<media::SupportedCodecProfileLevelsMemo>()),
-      app_media_capabilities_observer_binding_(this),
       supported_bitstream_audio_codecs_(kBitstreamAudioCodecNone) {
 #if defined(OS_ANDROID)
   DCHECK(::media::MediaCodecUtil::IsMediaCodecAvailable())
@@ -98,9 +98,9 @@
 void CastContentRendererClient::RenderThreadStarted() {
   // Register as observer for media capabilities
   content::RenderThread* thread = content::RenderThread::Get();
-  media::mojom::MediaCapsPtr media_caps;
-  thread->BindHostReceiver(mojo::MakeRequest(&media_caps));
-  media::mojom::MediaCapsObserverPtr proxy;
+  mojo::Remote<media::mojom::MediaCaps> media_caps;
+  thread->BindHostReceiver(media_caps.BindNewPipeAndPassReceiver());
+  mojo::PendingRemote<media::mojom::MediaCapsObserver> proxy;
   media_caps_observer_.reset(
       new media::MediaCapsObserverImpl(&proxy, supported_profiles_.get()));
   media_caps->AddObserver(std::move(proxy));
@@ -109,7 +109,8 @@
   // Register to observe memory pressure changes
   chromecast::mojom::MemoryPressureControllerPtr memory_pressure_controller;
   thread->BindHostReceiver(mojo::MakeRequest(&memory_pressure_controller));
-  chromecast::mojom::MemoryPressureObserverPtr memory_pressure_proxy;
+  mojo::PendingRemote<chromecast::mojom::MemoryPressureObserver>
+      memory_pressure_proxy;
   memory_pressure_observer_.reset(
       new MemoryPressureObserverImpl(&memory_pressure_proxy));
   memory_pressure_controller->AddObserver(std::move(memory_pressure_proxy));
@@ -174,13 +175,12 @@
   // APIs. The objects' lifetimes are bound to the RenderFrame's lifetime.
   new OnLoadScriptInjector(render_frame);
 
-  if (!app_media_capabilities_observer_binding_.is_bound()) {
-    mojom::ApplicationMediaCapabilitiesObserverPtr observer;
-    app_media_capabilities_observer_binding_.Bind(mojo::MakeRequest(&observer));
-    mojom::ApplicationMediaCapabilitiesPtr app_media_capabilities;
+  if (!app_media_capabilities_observer_receiver_.is_bound()) {
+    mojo::Remote<mojom::ApplicationMediaCapabilities> app_media_capabilities;
     render_frame->GetRemoteInterfaces()->GetInterface(
-        mojo::MakeRequest(&app_media_capabilities));
-    app_media_capabilities->AddObserver(std::move(observer));
+        app_media_capabilities.BindNewPipeAndPassReceiver());
+    app_media_capabilities->AddObserver(
+        app_media_capabilities_observer_receiver_.BindNewPipeAndPassRemote());
   }
 
 #if BUILDFLAG(ENABLE_CHROMECAST_EXTENSIONS)
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h
index 27e5f38..af3dbf2 100644
--- a/chromecast/renderer/cast_content_renderer_client.h
+++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -15,7 +15,7 @@
 #include "content/public/renderer/content_renderer_client.h"
 #include "media/base/audio_codecs.h"
 #include "media/base/audio_parameters.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 
 namespace extensions {
 class ExtensionsClient;
@@ -96,8 +96,8 @@
       prescient_networking_dispatcher_;
   std::unique_ptr<media::MediaCapsObserverImpl> media_caps_observer_;
   std::unique_ptr<media::SupportedCodecProfileLevelsMemo> supported_profiles_;
-  mojo::Binding<mojom::ApplicationMediaCapabilitiesObserver>
-      app_media_capabilities_observer_binding_;
+  mojo::Receiver<mojom::ApplicationMediaCapabilitiesObserver>
+      app_media_capabilities_observer_receiver_{this};
 #if !defined(OS_ANDROID)
   std::unique_ptr<MemoryPressureObserverImpl> memory_pressure_observer_;
 #endif
diff --git a/chromecast/renderer/media/media_caps_observer_impl.cc b/chromecast/renderer/media/media_caps_observer_impl.cc
index a389d81..18978858 100644
--- a/chromecast/renderer/media/media_caps_observer_impl.cc
+++ b/chromecast/renderer/media/media_caps_observer_impl.cc
@@ -12,10 +12,10 @@
 namespace media {
 
 MediaCapsObserverImpl::MediaCapsObserverImpl(
-    mojom::MediaCapsObserverPtr* proxy,
+    mojo::PendingRemote<mojom::MediaCapsObserver>* proxy,
     SupportedCodecProfileLevelsMemo* supported_profiles)
     : supported_profiles_(supported_profiles),
-      binding_(this, mojo::MakeRequest(proxy)) {}
+      receiver_(this, proxy->InitWithNewPipeAndPassReceiver()) {}
 
 MediaCapsObserverImpl::~MediaCapsObserverImpl() = default;
 
diff --git a/chromecast/renderer/media/media_caps_observer_impl.h b/chromecast/renderer/media/media_caps_observer_impl.h
index 37904fae3..04ee2bd 100644
--- a/chromecast/renderer/media/media_caps_observer_impl.h
+++ b/chromecast/renderer/media/media_caps_observer_impl.h
@@ -10,7 +10,8 @@
 #include "base/macros.h"
 #include "chromecast/common/mojom/media_caps.mojom.h"
 #include "chromecast/media/base/supported_codec_profile_levels_memo.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace chromecast {
@@ -18,7 +19,7 @@
 
 class MediaCapsObserverImpl : public mojom::MediaCapsObserver {
  public:
-  MediaCapsObserverImpl(mojom::MediaCapsObserverPtr* proxy,
+  MediaCapsObserverImpl(mojo::PendingRemote<mojom::MediaCapsObserver>* proxy,
                         SupportedCodecProfileLevelsMemo* supported_profiles);
   ~MediaCapsObserverImpl() override;
 
@@ -35,7 +36,7 @@
       mojom::CodecProfileLevelPtr codec_profile_level) override;
 
   SupportedCodecProfileLevelsMemo* supported_profiles_;
-  mojo::Binding<mojom::MediaCapsObserver> binding_;
+  mojo::Receiver<mojom::MediaCapsObserver> receiver_;
 
   DISALLOW_COPY_AND_ASSIGN(MediaCapsObserverImpl);
 };
diff --git a/chromecast/renderer/memory_pressure_observer_impl.cc b/chromecast/renderer/memory_pressure_observer_impl.cc
index ccd6568..ccbcb0b3 100644
--- a/chromecast/renderer/memory_pressure_observer_impl.cc
+++ b/chromecast/renderer/memory_pressure_observer_impl.cc
@@ -9,8 +9,8 @@
 namespace chromecast {
 
 MemoryPressureObserverImpl::MemoryPressureObserverImpl(
-    mojom::MemoryPressureObserverPtr* proxy)
-    : binding_(this, mojo::MakeRequest(proxy)) {}
+    mojo::PendingRemote<mojom::MemoryPressureObserver>* observer)
+    : receiver_(this, observer->InitWithNewPipeAndPassReceiver()) {}
 
 MemoryPressureObserverImpl::~MemoryPressureObserverImpl() = default;
 
diff --git a/chromecast/renderer/memory_pressure_observer_impl.h b/chromecast/renderer/memory_pressure_observer_impl.h
index fb71957..ac6398f 100644
--- a/chromecast/renderer/memory_pressure_observer_impl.h
+++ b/chromecast/renderer/memory_pressure_observer_impl.h
@@ -7,19 +7,21 @@
 
 #include "base/macros.h"
 #include "chromecast/common/mojom/memory_pressure.mojom.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 
 namespace chromecast {
 
 class MemoryPressureObserverImpl : public mojom::MemoryPressureObserver {
  public:
-  MemoryPressureObserverImpl(mojom::MemoryPressureObserverPtr* proxy);
+  MemoryPressureObserverImpl(
+      mojo::PendingRemote<mojom::MemoryPressureObserver>* observer);
   ~MemoryPressureObserverImpl() override;
 
  private:
   void MemoryPressureLevelChanged(int32_t pressure_level) override;
 
-  mojo::Binding<mojom::MemoryPressureObserver> binding_;
+  mojo::Receiver<mojom::MemoryPressureObserver> receiver_;
 
   DISALLOW_COPY_AND_ASSIGN(MemoryPressureObserverImpl);
 };
diff --git a/chromeos/components/proximity_auth/metrics.cc b/chromeos/components/proximity_auth/metrics.cc
index cb77635..1227423 100644
--- a/chromeos/components/proximity_auth/metrics.cc
+++ b/chromeos/components/proximity_auth/metrics.cc
@@ -12,6 +12,7 @@
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/numerics/ranges.h"
 #include "base/stl_util.h"
 #include "base/sys_byteorder.h"
 
@@ -50,7 +51,7 @@
 
 void RecordAuthProximityRollingRssi(int rolling_rssi) {
   if (rolling_rssi != kUnknownProximityValue)
-    rolling_rssi = std::min(50, std::max(-100, rolling_rssi));
+    rolling_rssi = base::ClampToRange(rolling_rssi, -100, 50);
 
   base::UmaHistogramSparse("EasyUnlock.AuthProximity.RollingRssi",
                            rolling_rssi);
diff --git a/chromeos/components/tether/device_status_util.cc b/chromeos/components/tether/device_status_util.cc
index 5d134a9..cdb3e829 100644
--- a/chromeos/components/tether/device_status_util.cc
+++ b/chromeos/components/tether/device_status_util.cc
@@ -4,26 +4,12 @@
 
 #include "chromeos/components/tether/device_status_util.h"
 
+#include "base/numerics/ranges.h"
+
 namespace chromeos {
 
 namespace tether {
 
-namespace {
-
-const char kDefaultCellCarrierName[] = "unknown-carrier";
-
-// Android signal strength is measured between 0 and 4 (inclusive), but Chrome
-// OS signal strength is measured between 0 and 100 (inclusive). In order to
-// convert between Android signal strength to Chrome OS signal strength, the
-// value must be multiplied by the below value.
-const int32_t kAndroidTetherHostToChromeOSSignalStrengthMultiplier = 25;
-
-int32_t ForceBetweenZeroAndOneHundred(int32_t value) {
-  return std::min(std::max(value, 0), 100);
-}
-
-}  // namespace
-
 void NormalizeDeviceStatus(const DeviceStatus& status,
                            std::string* carrier_out,
                            int32_t* battery_percentage_out,
@@ -31,6 +17,7 @@
   // Use a sentinel value if carrier information is not available. This value is
   // special-cased and replaced with a localized string in the settings UI.
   if (carrier_out) {
+    constexpr char kDefaultCellCarrierName[] = "unknown-carrier";
     *carrier_out =
         (!status.has_cell_provider() || status.cell_provider().empty())
             ? kDefaultCellCarrierName
@@ -44,15 +31,19 @@
   if (battery_percentage_out) {
     *battery_percentage_out =
         status.has_battery_percentage()
-            ? ForceBetweenZeroAndOneHundred(status.battery_percentage())
+            ? base::ClampToRange(status.battery_percentage(), 0, 100)
             : 100;
   }
   if (signal_strength_out) {
+    // Android signal strength is measured between 0 and 4 (inclusive), but
+    // Chrome OS signal strength is measured between 0 and 100 (inclusive). In
+    // order to convert between Android signal strength to Chrome OS signal
+    // strength, the value must be multiplied by the below value.
+    constexpr int32_t kConversionFactor = 100 / 4;
     *signal_strength_out =
         status.has_connection_strength()
-            ? ForceBetweenZeroAndOneHundred(
-                  kAndroidTetherHostToChromeOSSignalStrengthMultiplier *
-                  status.connection_strength())
+            ? base::ClampToRange(
+                  kConversionFactor * status.connection_strength(), 0, 100)
             : 100;
   }
 }
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc
index 5f3cbab..571fd810 100644
--- a/chromeos/constants/chromeos_switches.cc
+++ b/chromeos/constants/chromeos_switches.cc
@@ -433,10 +433,6 @@
 // TODO(984021): Remove when URL is sent by DMServer.
 const char kPublicAccountsSamlAclUrl[] = "public-accounts-saml-acl-url";
 
-// Url address of SAML provider for a SAML public session.
-// TODO(984021): Remove when URL is sent by DMServer.
-const char kPublicAccountsSamlUrl[] = "public-accounts-saml-url";
-
 // If set to "true", the profile requires policy during restart (policy load
 // must succeed, otherwise session restart should fail).
 const char kProfileRequiresPolicy[] = "profile-requires-policy";
diff --git a/chromeos/constants/chromeos_switches.h b/chromeos/constants/chromeos_switches.h
index 6b8603c..8552484 100644
--- a/chromeos/constants/chromeos_switches.h
+++ b/chromeos/constants/chromeos_switches.h
@@ -172,7 +172,6 @@
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kOobeTimerInterval[];
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const char kPublicAccountsSamlAclUrl[];
-COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kPublicAccountsSamlUrl[];
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const char kDisableArcCpuRestriction[];
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kProfileRequiresPolicy[];
diff --git a/chromeos/dbus/cicerone_client.cc b/chromeos/dbus/cicerone_client.cc
index 9c118f2..e6b9096e 100644
--- a/chromeos/dbus/cicerone_client.cc
+++ b/chromeos/dbus/cicerone_client.cc
@@ -90,6 +90,10 @@
     return is_pending_app_list_updates_signal_connected_;
   }
 
+  bool IsApplyAnsiblePlaybookProgressSignalConnected() override {
+    return is_apply_ansible_playbook_progress_signal_connected_;
+  }
+
   void LaunchContainerApplication(
       const vm_tools::cicerone::LaunchContainerApplicationRequest& request,
       DBusMethodCallback<vm_tools::cicerone::LaunchContainerApplicationResponse>
@@ -413,6 +417,29 @@
             weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
+  void ApplyAnsiblePlaybook(
+      const vm_tools::cicerone::ApplyAnsiblePlaybookRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::ApplyAnsiblePlaybookResponse>
+          callback) override {
+    dbus::MethodCall method_call(
+        vm_tools::cicerone::kVmCiceroneInterface,
+        vm_tools::cicerone::kApplyAnsiblePlaybookMethod);
+    dbus::MessageWriter writer(&method_call);
+
+    if (!writer.AppendProtoAsArrayOfBytes(request)) {
+      LOG(ERROR) << "Failed to encode ApplyAnsiblePlaybookRequest protobuf";
+      base::ThreadTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
+      return;
+    }
+
+    cicerone_proxy_->CallMethod(
+        &method_call, kDefaultTimeout.InMilliseconds(),
+        base::BindOnce(&CiceroneClientImpl::OnDBusProtoResponse<
+                           vm_tools::cicerone::ApplyAnsiblePlaybookResponse>,
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  }
+
   void WaitForServiceToBeAvailable(
       dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback)
       override {
@@ -517,6 +544,14 @@
                             weak_ptr_factory_.GetWeakPtr()),
         base::BindOnce(&CiceroneClientImpl::OnSignalConnected,
                        weak_ptr_factory_.GetWeakPtr()));
+    cicerone_proxy_->ConnectToSignal(
+        vm_tools::cicerone::kVmCiceroneInterface,
+        vm_tools::cicerone::kApplyAnsiblePlaybookProgressSignal,
+        base::BindRepeating(
+            &CiceroneClientImpl::OnApplyAnsiblePlaybookProgressSignal,
+            weak_ptr_factory_.GetWeakPtr()),
+        base::BindOnce(&CiceroneClientImpl::OnSignalConnected,
+                       weak_ptr_factory_.GetWeakPtr()));
   }
 
  private:
@@ -681,6 +716,18 @@
     }
   }
 
+  void OnApplyAnsiblePlaybookProgressSignal(dbus::Signal* signal) {
+    vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal proto;
+    dbus::MessageReader reader(signal);
+    if (!reader.PopArrayOfBytesAsProto(&proto)) {
+      LOG(ERROR) << "Failed to parse proto from DBus Signal";
+      return;
+    }
+    for (auto& observer : observer_list_) {
+      observer.OnApplyAnsiblePlaybookProgress(proto);
+    }
+  }
+
   void OnSignalConnected(const std::string& interface_name,
                          const std::string& signal_name,
                          bool is_connected) {
@@ -719,6 +766,9 @@
     } else if (signal_name ==
                vm_tools::cicerone::kPendingAppListUpdatesSignal) {
       is_pending_app_list_updates_signal_connected_ = is_connected;
+    } else if (signal_name ==
+               vm_tools::cicerone::kApplyAnsiblePlaybookProgressSignal) {
+      is_apply_ansible_playbook_progress_signal_connected_ = is_connected;
     } else {
       NOTREACHED();
     }
@@ -740,6 +790,7 @@
   bool is_export_lxd_container_progress_signal_connected_ = false;
   bool is_import_lxd_container_progress_signal_connected_ = false;
   bool is_pending_app_list_updates_signal_connected_ = false;
+  bool is_apply_ansible_playbook_progress_signal_connected_ = false;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
diff --git a/chromeos/dbus/cicerone_client.h b/chromeos/dbus/cicerone_client.h
index d780ea6..bacf22b 100644
--- a/chromeos/dbus/cicerone_client.h
+++ b/chromeos/dbus/cicerone_client.h
@@ -83,6 +83,12 @@
     virtual void OnPendingAppListUpdates(
         const vm_tools::cicerone::PendingAppListUpdatesSignal& signal) = 0;
 
+    // This is signaled from the container while a playbook is being applied
+    // via ApplyAnsiblePlaybook.
+    virtual void OnApplyAnsiblePlaybookProgress(
+        const vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal&
+            signal) = 0;
+
    protected:
     virtual ~Observer() = default;
   };
@@ -137,6 +143,9 @@
   // PendingAppListUpdatesSignal.
   virtual bool IsPendingAppListUpdatesSignalConnected() = 0;
 
+  // This should be true prior to calling ApplyAnsiblePlaybook.
+  virtual bool IsApplyAnsiblePlaybookProgressSignalConnected() = 0;
+
   // Launches an application inside a running Container.
   // |callback| is called after the method call finishes.
   virtual void LaunchContainerApplication(
@@ -238,6 +247,13 @@
       DBusMethodCallback<vm_tools::cicerone::CancelImportLxdContainerResponse>
           callback) = 0;
 
+  // Applies Ansible playbook.
+  // |callback| is called after the method call finishes.
+  virtual void ApplyAnsiblePlaybook(
+      const vm_tools::cicerone::ApplyAnsiblePlaybookRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::ApplyAnsiblePlaybookResponse>
+          callback) = 0;
+
   // Registers |callback| to run when the Cicerone service becomes available.
   // If the service is already available, or if connecting to the name-owner-
   // changed signal fails, |callback| will be run once asynchronously.
diff --git a/chromeos/dbus/fake_cicerone_client.cc b/chromeos/dbus/fake_cicerone_client.cc
index 67a9547..0608e6f 100644
--- a/chromeos/dbus/fake_cicerone_client.cc
+++ b/chromeos/dbus/fake_cicerone_client.cc
@@ -94,6 +94,10 @@
   return is_import_lxd_container_progress_signal_connected_;
 }
 
+bool FakeCiceroneClient::IsApplyAnsiblePlaybookProgressSignalConnected() {
+  return is_apply_ansible_playbook_progress_signal_connected_;
+}
+
 // Currently no tests need to change the output of this method. If you want to
 // add one, make it return a variable like the above examples.
 bool FakeCiceroneClient::IsPendingAppListUpdatesSignalConnected() {
@@ -280,6 +284,15 @@
                                 cancel_import_lxd_container_response_));
 }
 
+void FakeCiceroneClient::ApplyAnsiblePlaybook(
+    const vm_tools::cicerone::ApplyAnsiblePlaybookRequest& request,
+    DBusMethodCallback<vm_tools::cicerone::ApplyAnsiblePlaybookResponse>
+        callback) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(std::move(callback), apply_ansible_playbook_response_));
+}
+
 void FakeCiceroneClient::NotifyLxdContainerCreated(
     const vm_tools::cicerone::LxdContainerCreatedSignal& proto) {
   for (auto& observer : observer_list_) {
@@ -343,4 +356,11 @@
   }
 }
 
+void FakeCiceroneClient::NotifyApplyAnsiblePlaybookProgress(
+    const vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal& signal) {
+  for (auto& observer : observer_list_) {
+    observer.OnApplyAnsiblePlaybookProgress(signal);
+  }
+}
+
 }  // namespace chromeos
diff --git a/chromeos/dbus/fake_cicerone_client.h b/chromeos/dbus/fake_cicerone_client.h
index f854294..47f6d0c7 100644
--- a/chromeos/dbus/fake_cicerone_client.h
+++ b/chromeos/dbus/fake_cicerone_client.h
@@ -37,6 +37,7 @@
   bool IsExportLxdContainerProgressSignalConnected() override;
   bool IsImportLxdContainerProgressSignalConnected() override;
   bool IsPendingAppListUpdatesSignalConnected() override;
+  bool IsApplyAnsiblePlaybookProgressSignalConnected() override;
   void LaunchContainerApplication(
       const vm_tools::cicerone::LaunchContainerApplicationRequest& request,
       DBusMethodCallback<vm_tools::cicerone::LaunchContainerApplicationResponse>
@@ -100,6 +101,10 @@
       const vm_tools::cicerone::CancelImportLxdContainerRequest& request,
       DBusMethodCallback<vm_tools::cicerone::CancelImportLxdContainerResponse>
           callback) override;
+  void ApplyAnsiblePlaybook(
+      const vm_tools::cicerone::ApplyAnsiblePlaybookRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::ApplyAnsiblePlaybookResponse>
+          callback) override;
   void WaitForServiceToBeAvailable(
       dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) override;
 
@@ -232,10 +237,14 @@
   void set_lxd_container_os_release(vm_tools::cicerone::OsRelease os_release) {
     lxd_container_os_release_ = std::move(os_release);
   }
-
   void set_send_container_started_signal(bool send) {
     send_container_started_signal_ = send;
   }
+  void set_apply_ansible_playbook_response(
+      const vm_tools::cicerone::ApplyAnsiblePlaybookResponse&
+          apply_ansible_playbook_response) {
+    apply_ansible_playbook_response_ = apply_ansible_playbook_response;
+  }
 
   // Additional functions to allow tests to trigger Signals.
   void NotifyLxdContainerCreated(
@@ -258,6 +267,8 @@
       const vm_tools::cicerone::UninstallPackageProgressSignal& signal);
   void NotifyPendingAppListUpdates(
       const vm_tools::cicerone::PendingAppListUpdatesSignal& signal);
+  void NotifyApplyAnsiblePlaybookProgress(
+      const vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal& signal);
 
  protected:
   void Init(dbus::Bus* bus) override {}
@@ -274,6 +285,7 @@
   bool is_lxd_container_starting_signal_connected_ = true;
   bool is_export_lxd_container_progress_signal_connected_ = true;
   bool is_import_lxd_container_progress_signal_connected_ = true;
+  bool is_apply_ansible_playbook_progress_signal_connected_ = true;
 
   std::string last_container_username_;
   bool send_container_started_signal_ = true;
@@ -313,6 +325,8 @@
       cancel_export_lxd_container_response_;
   vm_tools::cicerone::CancelImportLxdContainerResponse
       cancel_import_lxd_container_response_;
+  vm_tools::cicerone::ApplyAnsiblePlaybookResponse
+      apply_ansible_playbook_response_;
 
   vm_tools::cicerone::OsRelease lxd_container_os_release_;
 
diff --git a/components/arc/net/arc_net_host_impl.cc b/components/arc/net/arc_net_host_impl.cc
index c970423..c04353b 100644
--- a/components/arc/net/arc_net_host_impl.cc
+++ b/components/arc/net/arc_net_host_impl.cc
@@ -858,7 +858,7 @@
   std::unique_ptr<base::Value> result =
       std::make_unique<base::Value>(base::Value::Type::LIST);
   for (const auto& item : string_list) {
-    result->GetList().emplace_back(item);
+    result->Append(item);
   }
   return result;
 }
diff --git a/components/autofill/core/browser/logging/log_buffer.cc b/components/autofill/core/browser/logging/log_buffer.cc
index 8bbd7a9..21ec495 100644
--- a/components/autofill/core/browser/logging/log_buffer.cc
+++ b/components/autofill/core/browser/logging/log_buffer.cc
@@ -40,7 +40,7 @@
   DCHECK(!IsTextNode(parent));
 
   if (auto* children = parent.FindListKey("children")) {
-    children->GetList().push_back(std::move(new_child));
+    children->Append(std::move(new_child));
     return;
   }
 
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
index 4364f145..bb3065a 100644
--- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
+++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
@@ -439,7 +439,7 @@
   base::Value authenticator_transport_list =
       base::Value(base::Value::Type::LIST);
   for (FidoTransportProtocol protocol : attestation_response->transports) {
-    authenticator_transport_list.GetList().push_back(
+    authenticator_transport_list.Append(
         base::Value(base::ToUpperASCII(device::ToString(protocol))));
   }
 
diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc
index b097a05..b24b3710 100644
--- a/components/autofill/core/browser/payments/payments_client.cc
+++ b/components/autofill/core/browser/payments/payments_client.cc
@@ -142,7 +142,7 @@
                             base::Value& list) {
   const base::string16 value = profile.GetInfo(type, app_locale);
   if (!value.empty())
-    list.GetList().emplace_back(value);
+    list.Append(value);
 }
 
 // Returns a dictionary with the structure expected by Payments RPCs, containing
@@ -228,7 +228,7 @@
 
   base::Value active_chrome_experiments(base::Value::Type::LIST);
   for (const char* it : active_experiments)
-    active_chrome_experiments.GetList().emplace_back(it);
+    active_chrome_experiments.Append(it);
 
   request_dict.SetKey("active_chrome_experiments",
                       std::move(active_chrome_experiments));
@@ -568,8 +568,7 @@
       // min address is not possible). The final parameter directs
       // BuildAddressDictionary to omit names and phone numbers, which aren't
       // useful for these purposes.
-      addresses.GetList().push_back(
-          BuildAddressDictionary(profile, app_locale_, false));
+      addresses.Append(BuildAddressDictionary(profile, app_locale_, false));
     }
     request_dict.SetKey("address", std::move(addresses));
 
@@ -740,8 +739,7 @@
 
     base::Value addresses(base::Value::Type::LIST);
     for (const AutofillProfile& profile : request_details_.profiles) {
-      addresses.GetList().push_back(
-          BuildAddressDictionary(profile, app_locale, true));
+      addresses.Append(BuildAddressDictionary(profile, app_locale, true));
     }
     request_dict.SetKey("address", std::move(addresses));
 
@@ -859,7 +857,7 @@
     for (size_t index = 0; index < migratable_credit_cards_.size(); ++index) {
       std::string pan_field_name = GetPanFieldName(index);
       // Generate credit card dictionary.
-      migrate_cards.GetList().push_back(BuildCreditCardDictionary(
+      migrate_cards.Append(BuildCreditCardDictionary(
           migratable_credit_cards_[index].credit_card(), app_locale,
           pan_field_name));
       // Append pan data to the |all_pans_data|.
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc
index a1de20ba8..c454cc8 100644
--- a/components/browser_sync/profile_sync_components_factory_impl.cc
+++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -322,18 +322,8 @@
 
 #if defined(OS_CHROMEOS)
   if (!disabled_types.Has(syncer::PRINTERS)) {
-    // TODO(crbug.com/867801) This still uses a proxy delegate even though the
-    // model lives on the UI thread. Switching to forwarding delegate causes
-    // cryptic test failures on chromeos. Fix that and switch to the forwarding
-    // delegate.
-    controllers.push_back(std::make_unique<ModelTypeController>(
-        syncer::PRINTERS,
-        std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
-            ui_thread_,
-            base::BindRepeating(&browser_sync::BrowserSyncClient::
-                                    GetControllerDelegateForModelType,
-                                base::Unretained(sync_client_),
-                                syncer::PRINTERS))));
+    controllers.push_back(
+        CreateModelTypeControllerForModelRunningOnUIThread(syncer::PRINTERS));
   }
   if (!disabled_types.Has(syncer::WIFI_CONFIGURATIONS) &&
       base::FeatureList::IsEnabled(switches::kSyncWifiConfigurations)) {
diff --git a/components/cast_channel/cast_message_util.cc b/components/cast_channel/cast_message_util.cc
index 42ddb520..d6b8fb8 100644
--- a/components/cast_channel/cast_message_util.cc
+++ b/components/cast_channel/cast_message_util.cc
@@ -341,7 +341,7 @@
               Value(EnumToString<CastMessageType,
                                  CastMessageType::kGetAppAvailability>()));
   Value app_id_value(Value::Type::LIST);
-  app_id_value.GetList().push_back(Value(app_id));
+  app_id_value.Append(Value(app_id));
   dict.SetKey("appId", std::move(app_id_value));
   dict.SetKey("requestId", Value(request_id));
 
diff --git a/components/cast_channel/cast_socket_unittest.cc b/components/cast_channel/cast_socket_unittest.cc
index 8942f08c..18e879b 100644
--- a/components/cast_channel/cast_socket_unittest.cc
+++ b/components/cast_channel/cast_socket_unittest.cc
@@ -34,6 +34,7 @@
 #include "components/cast_channel/proto/cast_channel.pb.h"
 #include "content/public/test/browser_task_environment.h"
 #include "crypto/rsa_private_key.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/address_list.h"
 #include "net/base/net_errors.h"
 #include "net/cert/pem_tokenizer.h"
@@ -387,7 +388,7 @@
     url_request_context_.set_client_socket_factory(&client_socket_factory_);
     url_request_context_.Init();
     network_context_ = std::make_unique<network::NetworkContext>(
-        nullptr, mojo::MakeRequest(&network_context_ptr_),
+        nullptr, network_context_remote_.BindNewPipeAndPassReceiver(),
         &url_request_context_,
         /*cors_exempt_header_list=*/std::vector<std::string>());
   }
@@ -403,7 +404,7 @@
   content::BrowserTaskEnvironment task_environment_;
   net::TestURLRequestContext url_request_context_;
   std::unique_ptr<network::NetworkContext> network_context_;
-  network::mojom::NetworkContextPtr network_context_ptr_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
   Logger* logger_;
   CompleteHandler handler_;
   std::unique_ptr<MockCastSocketObserver> observer_;
diff --git a/components/cloud_devices/common/description_items_inl.h b/components/cloud_devices/common/description_items_inl.h
index 096d366..8ed2fea 100644
--- a/components/cloud_devices/common/description_items_inl.h
+++ b/components/cloud_devices/common/description_items_inl.h
@@ -68,7 +68,7 @@
   for (const Option& option : options_) {
     base::Value option_value(base::Value::Type::DICTIONARY);
     Traits::Save(option, &option_value);
-    options_list->GetList().emplace_back(std::move(option_value));
+    options_list->Append(std::move(option_value));
   }
 }
 
@@ -157,7 +157,7 @@
     if (base::checked_cast<int>(i) == default_idx_)
       option_value.SetKey(json::kKeyIsDefault, base::Value(true));
     Traits::Save(options_[i], &option_value);
-    options_list.GetList().emplace_back(std::move(option_value));
+    options_list.Append(std::move(option_value));
   }
   dict->SetKey(json::kKeyOption, std::move(options_list));
 }
diff --git a/components/cloud_devices/common/printer_description.cc b/components/cloud_devices/common/printer_description.cc
index b2e9e9d..a3cf56c 100644
--- a/components/cloud_devices/common/printer_description.cc
+++ b/components/cloud_devices/common/printer_description.cc
@@ -1323,7 +1323,7 @@
         interval.SetKey(kPageRangeStart, base::Value(option[i].start));
         if (option[i].end < kMaxPageNumber)
           interval.SetKey(kPageRangeEnd, base::Value(option[i].end));
-        list.GetList().emplace_back(std::move(interval));
+        list.Append(std::move(interval));
       }
       dict->SetKey(kPageRangeInterval, std::move(list));
     }
diff --git a/components/content_settings/core/browser/content_settings_policy_provider.cc b/components/content_settings/core/browser/content_settings_policy_provider.cc
index 4e57830..f87f391e 100644
--- a/components/content_settings/core/browser/content_settings_policy_provider.cc
+++ b/components/content_settings/core/browser/content_settings_policy_provider.cc
@@ -357,8 +357,7 @@
 
     // Don't pass removed values from |value|, because base::Values read with
     // JSONReader use a shared string buffer. Instead, Clone() here.
-    filters_map[pattern_str].FindKey("filters")->GetList().push_back(
-        filter->Clone());
+    filters_map[pattern_str].FindKey("filters")->Append(filter->Clone());
   }
 
   for (const auto& it : filters_map) {
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
index de9c4ca..32f7ce59 100644
--- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
+++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
@@ -169,9 +169,9 @@
 network::mojom::URLLoaderFactory*
 WarmupURLFetcher::GetNetworkServiceURLLoaderFactory(
     const DataReductionProxyServer& proxy_server) {
-  network::mojom::NetworkContextPtr context;
+  context_.reset();
   BindNetworkContext(create_custom_proxy_config_callback_.Run({proxy_server}),
-                     mojo::MakeRequest(&context_), user_agent_);
+                     context_.BindNewPipeAndPassReceiver(), user_agent_);
 
   auto factory_params = network::mojom::URLLoaderFactoryParams::New();
   factory_params->process_id = network::mojom::kBrowserProcessId;
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h
index 92edc0c..51a1c48d 100644
--- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h
+++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h
@@ -13,6 +13,7 @@
 #include "base/optional.h"
 #include "base/sequence_checker.h"
 #include "base/timer/timer.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/proxy_server.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 
@@ -130,7 +131,7 @@
 
   CreateCustomProxyConfigCallback create_custom_proxy_config_callback_;
   network::mojom::URLLoaderFactoryPtr url_loader_factory_;
-  network::mojom::NetworkContextPtr context_;
+  mojo::Remote<network::mojom::NetworkContext> context_;
 
   // Callback that should be executed when the fetching of the warmup URL is
   // completed.
diff --git a/components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.cc b/components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.cc
index a08f307..b8e88b5 100644
--- a/components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.cc
+++ b/components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.cc
@@ -80,7 +80,7 @@
           celllangs_cached->GetList()[index] =
               GetCellLanguagePairValue(cell.parent(level), language);
         } else {
-          celllangs_cached->GetList().push_back(
+          celllangs_cached->Append(
               GetCellLanguagePairValue(cell.parent(level), language));
         }
       }
diff --git a/components/language/core/browser/fluent_language_model_unittest.cc b/components/language/core/browser/fluent_language_model_unittest.cc
index ff62558..00b2658 100644
--- a/components/language/core/browser/fluent_language_model_unittest.cc
+++ b/components/language/core/browser/fluent_language_model_unittest.cc
@@ -62,8 +62,8 @@
 TEST_F(FluentLanguageModelTest, AllFluent) {
   prefs_->SetString(prefs::kAcceptLanguages, "ja,fr");
   base::ListValue fluent_languages;
-  fluent_languages.GetList().emplace_back("fr");
-  fluent_languages.GetList().emplace_back("ja");
+  fluent_languages.Append("fr");
+  fluent_languages.Append("ja");
   prefs_->Set(prefs::kFluentLanguages, fluent_languages);
 
   FluentLanguageModel model(prefs_.get(), prefs::kAcceptLanguages);
@@ -74,8 +74,8 @@
 TEST_F(FluentLanguageModelTest, OneNonFluent) {
   prefs_->SetString(prefs::kAcceptLanguages, "ja,en,fr");
   base::ListValue fluent_languages;
-  fluent_languages.GetList().emplace_back("fr");
-  fluent_languages.GetList().emplace_back("ja");
+  fluent_languages.Append("fr");
+  fluent_languages.Append("ja");
   prefs_->Set(prefs::kFluentLanguages, fluent_languages);
 
   FluentLanguageModel model(prefs_.get(), prefs::kAcceptLanguages);
@@ -86,7 +86,7 @@
 TEST_F(FluentLanguageModelTest, OneFluent) {
   prefs_->SetString(prefs::kAcceptLanguages, "ja,en,fr");
   base::ListValue fluent_languages;
-  fluent_languages.GetList().emplace_back("ja");
+  fluent_languages.Append("ja");
   prefs_->Set(prefs::kFluentLanguages, fluent_languages);
 
   FluentLanguageModel model(prefs_.get(), prefs::kAcceptLanguages);
diff --git a/components/language/core/browser/language_prefs.cc b/components/language/core/browser/language_prefs.cc
index 769e262..d5e4c09 100644
--- a/components/language/core/browser/language_prefs.cc
+++ b/components/language/core/browser/language_prefs.cc
@@ -63,7 +63,7 @@
   std::string canonical_lang = language;
   language::ToTranslateLanguageSynonym(&canonical_lang);
   ListPrefUpdate update(prefs_, language::prefs::kFluentLanguages);
-  update->GetList().emplace_back(std::move(canonical_lang));
+  update->Append(std::move(canonical_lang));
 }
 
 void LanguagePrefs::ClearFluent(const std::string& language) {
@@ -115,7 +115,7 @@
 #endif
   base::Value language_values(base::Value::Type::LIST);
   for (const std::string& language : languages)
-    language_values.GetList().emplace_back(language);
+    language_values.Append(language);
 
   return language_values;
 }
diff --git a/components/mirroring/service/session.cc b/components/mirroring/service/session.cc
index 93c9d8b..5a80943 100644
--- a/components/mirroring/service/session.cc
+++ b/components/mirroring/service/session.cc
@@ -392,7 +392,8 @@
   DCHECK(resource_provider_);
   mirror_settings_.SetResolutionContraints(max_resolution.width(),
                                            max_resolution.height());
-  resource_provider_->GetNetworkContext(mojo::MakeRequest(&network_context_));
+  resource_provider_->GetNetworkContext(
+      network_context_.BindNewPipeAndPassReceiver());
 
   if (session_params->type != mojom::SessionType::AUDIO_ONLY &&
       io_task_runner) {
diff --git a/components/mirroring/service/session.h b/components/mirroring/service/session.h
index 34a3543..8444dab 100644
--- a/components/mirroring/service/session.h
+++ b/components/mirroring/service/session.h
@@ -25,6 +25,7 @@
 #include "media/mojo/mojom/video_encode_accelerator.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 
 namespace media {
@@ -162,7 +163,7 @@
 
   MessageDispatcher message_dispatcher_;
 
-  network::mojom::NetworkContextPtr network_context_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_;
 
   base::Optional<SessionMonitor> session_monitor_;
 
diff --git a/components/mirroring/service/udp_socket_client_unittest.cc b/components/mirroring/service/udp_socket_client_unittest.cc
index 623936a..ae84a33 100644
--- a/components/mirroring/service/udp_socket_client_unittest.cc
+++ b/components/mirroring/service/udp_socket_client_unittest.cc
@@ -17,7 +17,7 @@
 #include "components/mirroring/service/fake_network_service.h"
 #include "media/cast/net/cast_transport_config.h"
 #include "media/cast/test/utility/net_utility.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/ip_endpoint.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -31,9 +31,9 @@
  public:
   UdpSocketClientTest() {
     network_context_ = std::make_unique<MockNetworkContext>(
-        mojo::MakeRequest(&network_context_ptr_));
+        network_context_remote_.BindNewPipeAndPassReceiver());
     udp_transport_client_ = std::make_unique<UdpSocketClient>(
-        media::cast::test::GetFreeLocalPort(), network_context_ptr_.get(),
+        media::cast::test::GetFreeLocalPort(), network_context_remote_.get(),
         base::OnceClosure());
   }
 
@@ -48,7 +48,7 @@
 
  protected:
   base::test::TaskEnvironment task_environment_;
-  network::mojom::NetworkContextPtr network_context_ptr_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
   std::unique_ptr<MockNetworkContext> network_context_;
   std::unique_ptr<UdpSocketClient> udp_transport_client_;
   std::unique_ptr<Packet> received_packet_;
diff --git a/components/net_log/net_export_file_writer_unittest.cc b/components/net_log/net_export_file_writer_unittest.cc
index caaf54a..28f43d4 100644
--- a/components/net_log/net_export_file_writer_unittest.cc
+++ b/components/net_log/net_export_file_writer_unittest.cc
@@ -21,6 +21,7 @@
 #include "base/test/task_environment.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "net/base/network_change_notifier.h"
 #include "net/base/test_completion_callback.h"
@@ -268,7 +269,8 @@
     params->initial_proxy_config =
         net::ProxyConfigWithAnnotation::CreateDirect();
     network_context_ = std::make_unique<network::NetworkContext>(
-        network_service_.get(), mojo::MakeRequest(&network_context_ptr_),
+        network_service_.get(),
+        network_context_remote_.BindNewPipeAndPassReceiver(),
         std::move(params));
 
     // Override |file_writer_|'s default-log-base-directory-getter to
@@ -435,7 +437,7 @@
   TestStateObserver* test_state_observer() { return &test_state_observer_; }
 
   network::mojom::NetworkContext* network_context() {
-    return network_context_ptr_.get();
+    return network_context_remote_.get();
   }
 
  private:
@@ -444,10 +446,10 @@
   std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
   std::unique_ptr<network::NetworkService> network_service_;
 
-  network::mojom::NetworkContextPtr network_context_ptr_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
   std::unique_ptr<network::NetworkContext> network_context_;
 
-  // |file_writer_| is initialized after |network_context_ptr_| since
+  // |file_writer_| is initialized after |network_context_remote_| since
   // |file_writer_| destructor can talk to mojo objects owned by
   // |network_context_|.
   NetExportFileWriter file_writer_;
diff --git a/components/ntp_snippets/remote/json_request.cc b/components/ntp_snippets/remote/json_request.cc
index 0dc2ecd..09059e1 100644
--- a/components/ntp_snippets/remote/json_request.cc
+++ b/components/ntp_snippets/remote/json_request.cc
@@ -351,8 +351,7 @@
     exclusive_category_parameters.SetInteger("numSuggestions",
                                              params_.count_to_fetch);
     base::ListValue category_parameters;
-    category_parameters.GetList().push_back(
-        std::move(exclusive_category_parameters));
+    category_parameters.Append(std::move(exclusive_category_parameters));
     request->SetKey("categoryParameters", std::move(category_parameters));
   }
 
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index b6752a5..e2619e98 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -163,6 +163,8 @@
     "password_sync_util.h",
     "password_ui_utils.cc",
     "password_ui_utils.h",
+    "possible_username_data.cc",
+    "possible_username_data.h",
     "psl_matching_helper.cc",
     "psl_matching_helper.h",
     "site_affiliation/asset_link_data.cc",
@@ -525,6 +527,7 @@
     "password_store_unittest.cc",
     "password_sync_util_unittest.cc",
     "password_ui_utils_unittest.cc",
+    "possible_username_data_unittest.cc",
     "psl_matching_helper_unittest.cc",
     "site_affiliation/asset_link_data_unittest.cc",
     "sql_table_builder_unittest.cc",
diff --git a/components/password_manager/core/browser/hash_password_manager.cc b/components/password_manager/core/browser/hash_password_manager.cc
index 9a8ee08c..4e5fae3 100644
--- a/components/password_manager/core/browser/hash_password_manager.cc
+++ b/components/password_manager/core/browser/hash_password_manager.cc
@@ -355,14 +355,14 @@
     }
   }
   if (replace_old_entry) {
-    update->GetList().push_back(std::move(encrypted_password_hash_entry));
+    update->Append(std::move(encrypted_password_hash_entry));
     return true;
   }
 
   if (update->GetList().size() >= kMaxPasswordHashDataDictSize)
     RemoveOldestSignInPasswordHashData(&update->GetList());
 
-  update->GetList().push_back(std::move(encrypted_password_hash_entry));
+  update->Append(std::move(encrypted_password_hash_entry));
   return true;
 }
 
diff --git a/components/password_manager/core/browser/hsts_query_unittest.cc b/components/password_manager/core/browser/hsts_query_unittest.cc
index 2833a64..98a9b11 100644
--- a/components/password_manager/core/browser/hsts_query_unittest.cc
+++ b/components/password_manager/core/browser/hsts_query_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/test/task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/url_request/url_request_test_util.h"
 #include "services/network/network_context.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -63,7 +64,7 @@
             base::ThreadTaskRunnerHandle::Get())),
         network_context_(std::make_unique<network::NetworkContext>(
             nullptr,
-            mojo::MakeRequest(&network_context_pipe_),
+            network_context_remote_.BindNewPipeAndPassReceiver(),
             request_context_->GetURLRequestContext(),
             /*cors_exempt_header_list=*/std::vector<std::string>())) {}
 
@@ -73,7 +74,7 @@
   // Used by request_context_.
   base::test::SingleThreadTaskEnvironment task_environment_;
   scoped_refptr<net::TestURLRequestContextGetter> request_context_;
-  network::mojom::NetworkContextPtr network_context_pipe_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
   std::unique_ptr<network::NetworkContext> network_context_;
 
   DISALLOW_COPY_AND_ASSIGN(HSTSQueryTest);
diff --git a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
index 94a7cc91..83e88abe 100644
--- a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
+++ b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
@@ -17,6 +17,7 @@
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/url_request/url_request_test_util.h"
 #include "services/network/network_context.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -174,9 +175,9 @@
 
   auto request_context = base::MakeRefCounted<net::TestURLRequestContextGetter>(
       base::ThreadTaskRunnerHandle::Get());
-  network::mojom::NetworkContextPtr network_context_pipe;
+  mojo::Remote<network::mojom::NetworkContext> network_context_remote;
   auto network_context = std::make_unique<network::NetworkContext>(
-      nullptr, mojo::MakeRequest(&network_context_pipe),
+      nullptr, network_context_remote.BindNewPipeAndPassReceiver(),
       request_context->GetURLRequestContext(),
       /*cors_exempt_header_list=*/std::vector<std::string>());
 
@@ -201,13 +202,13 @@
   HttpCredentialCleaner cleaner(
       store_,
       base::BindLambdaForTesting([&]() -> network::mojom::NetworkContext* {
-        // This needs to be network_context_pipe.get() and
+        // This needs to be network_context_remote.get() and
         // not network_context.get() to make HSTS queries asynchronous, which
         // is what the progress tracking logic in HttpMetricsMigrationReporter
         // assumes.  This also matches reality, since
         // StoragePartition::GetNetworkContext will return a mojo pipe
         // even in the in-process case.
-        return network_context_pipe.get();
+        return network_context_remote.get();
       }),
       &prefs);
   EXPECT_CALL(observer, CleaningCompleted);
@@ -282,9 +283,9 @@
     auto request_context =
         base::MakeRefCounted<net::TestURLRequestContextGetter>(
             base::ThreadTaskRunnerHandle::Get());
-    network::mojom::NetworkContextPtr network_context_pipe;
+    mojo::Remote<network::mojom::NetworkContext> network_context_remote;
     auto network_context = std::make_unique<network::NetworkContext>(
-        nullptr, mojo::MakeRequest(&network_context_pipe),
+        nullptr, network_context_remote.BindNewPipeAndPassReceiver(),
         request_context->GetURLRequestContext(),
         /*cors_exempt_header_list=*/std::vector<std::string>());
 
@@ -292,13 +293,13 @@
     HttpCredentialCleaner cleaner(
         password_store,
         base::BindLambdaForTesting([&]() -> network::mojom::NetworkContext* {
-          // This needs to be network_context_pipe.get() and
+          // This needs to be network_context_remote.get() and
           // not network_context.get() to make HSTS queries asynchronous, which
           // is what the progress tracking logic in HttpMetricsMigrationReporter
           // assumes.  This also matches reality, since
           // StoragePartition::GetNetworkContext will return a mojo pipe
           // even in the in-process case.
-          return network_context_pipe.get();
+          return network_context_remote.get();
         }),
         &prefs);
     EXPECT_TRUE(cleaner.NeedsCleaning());
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 5cdc2e3..c3135874 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -28,6 +28,7 @@
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_driver.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
+#include "components/password_manager/core/browser/possible_username_data.h"
 #include "components/password_manager/core/browser/statistics_table.h"
 
 using autofill::FormData;
@@ -625,7 +626,8 @@
 
 bool PasswordFormManager::ProvisionallySave(
     const FormData& submitted_form,
-    const PasswordManagerDriver* driver) {
+    const PasswordManagerDriver* driver,
+    const PossibleUsernameData* possible_username) {
   DCHECK(DoesManage(submitted_form, driver));
 
   std::unique_ptr<PasswordForm> parsed_submitted_form =
@@ -644,6 +646,13 @@
   is_submitted_ = true;
   CalculateFillingAssistanceMetric(submitted_form);
 
+  if (parsed_submitted_form_->username_value.empty() && possible_username &&
+      IsPossibleUsernameValid(*possible_username,
+                              parsed_submitted_form_->signon_realm,
+                              base::Time::Now())) {
+    parsed_submitted_form_->username_value = possible_username->value;
+  }
+
   CreatePendingCredentials();
   return true;
 }
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h
index 0451bcc..ee296dd 100644
--- a/components/password_manager/core/browser/password_form_manager.h
+++ b/components/password_manager/core/browser/password_form_manager.h
@@ -33,6 +33,7 @@
 class PasswordGenerationState;
 class PasswordManagerClient;
 class PasswordManagerDriver;
+struct PossibleUsernameData;
 
 // This class helps with filling the observed form and with saving/updating the
 // stored information about it. It is aimed to replace PasswordFormManager and
@@ -87,8 +88,12 @@
   // |submitted_form| and |driver|) then saves |submitted_form| to
   // |submitted_form_| field, sets |is_submitted| = true and returns true.
   // Otherwise returns false.
+  // If as a result of the parsing the username is not found, the
+  // |possible_username->value| is chosen as username if it looks like an
+  // username and came from the same domain as |submitted_form|.
   bool ProvisionallySave(const autofill::FormData& submitted_form,
-                         const PasswordManagerDriver* driver);
+                         const PasswordManagerDriver* driver,
+                         const PossibleUsernameData* possible_username);
 
   // If |submitted_form| is managed by *this then saves |submitted_form| to
   // |submitted_form_| field, sets |is_submitted| = true and returns true.
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 3c017d7..539abc58 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -24,6 +24,7 @@
 #include "components/password_manager/core/browser/password_form_manager_for_ui.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
 #include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/possible_username_data.h"
 #include "components/password_manager/core/browser/stub_form_saver.h"
 #include "components/password_manager/core/browser/stub_password_manager_client.h"
 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
@@ -560,7 +561,8 @@
 
 TEST_F(PasswordFormManagerTest, SetSubmitted) {
   EXPECT_FALSE(form_manager_->is_submitted());
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
   EXPECT_TRUE(form_manager_->is_submitted());
 
   FormData another_form = submitted_form_;
@@ -568,13 +570,15 @@
 #if !defined(OS_IOS)
   // |another_form| is managed because the same |unique_renderer_id| as
   // |observed_form_|.
-  EXPECT_TRUE(form_manager_->ProvisionallySave(another_form, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(another_form, &driver_, nullptr));
   EXPECT_TRUE(form_manager_->is_submitted());
 #endif
 }
 
 TEST_F(PasswordFormManagerTest, SetSubmittedMultipleTimes) {
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
   EXPECT_TRUE(form_manager_->is_submitted());
 
   // Make the submitted form to be invalid password form.
@@ -582,7 +586,8 @@
 
   // Expect that |form_manager_| is still in submitted state because the first
   // time the submited form was valid.
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
   EXPECT_TRUE(form_manager_->is_submitted());
   EXPECT_TRUE(form_manager_->GetSubmittedForm());
 }
@@ -659,7 +664,8 @@
 
   const base::Time kNow = base::Time::Now();
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
 
   const PasswordForm& pending_credentials =
       form_manager_->GetPendingCredentials();
@@ -675,7 +681,8 @@
   TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
   SetNonFederatedAndNotifyFetchCompleted({&saved_match_});
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
   CheckPendingCredentials(parsed_submitted_form_,
                           form_manager_->GetPendingCredentials());
   EXPECT_EQ(UserAction::kOverrideUsernameAndPassword,
@@ -699,7 +706,8 @@
   for (bool is_incognito : {false, true}) {
     EXPECT_CALL(client_, IsIncognito).WillOnce(Return(is_incognito));
     form_manager_->Fill();
-    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+    EXPECT_TRUE(
+        form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
     CheckPendingCredentials(/* expected */ saved_match_,
                             form_manager_->GetPendingCredentials());
     EXPECT_EQ(is_incognito ? UserAction::kChoose : UserAction::kNone,
@@ -724,7 +732,8 @@
   submitted_form_.fields[kPasswordFieldIndex].value =
       saved_match_.password_value;
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
   CheckPendingCredentials(expected, form_manager_->GetPendingCredentials());
   EXPECT_EQ(UserAction::kChoosePslMatch,
             form_manager_->GetMetricsRecorder()->GetUserAction());
@@ -742,7 +751,8 @@
   submitted_form_.fields[kUsernameFieldIndex].value =
       saved_match_.username_value;
   submitted_form_.fields[kPasswordFieldIndex].value = expected.password_value;
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
   CheckPendingCredentials(expected, form_manager_->GetPendingCredentials());
   EXPECT_EQ(UserAction::kOverridePassword,
             form_manager_->GetMetricsRecorder()->GetUserAction());
@@ -761,7 +771,8 @@
   PasswordForm expected = saved_match_;
   expected.password_value = ASCIIToUTF16("verystrongpassword");
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
   CheckPendingCredentials(expected, form_manager_->GetPendingCredentials());
   EXPECT_EQ(UserAction::kOverridePassword,
             form_manager_->GetMetricsRecorder()->GetUserAction());
@@ -782,7 +793,8 @@
   PasswordForm expected = saved_match_;
   expected.password_value = ASCIIToUTF16("verystrongpassword");
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
   CheckPendingCredentials(expected, form_manager_->GetPendingCredentials());
 }
 
@@ -801,7 +813,8 @@
 
   form_manager_->ProcessServerPredictions(predictions);
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(anonymous_signup, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(anonymous_signup, &driver_, nullptr));
   EXPECT_EQ(ASCIIToUTF16("a password"),
             form_manager_->GetPendingCredentials().password_value);
 }
@@ -821,7 +834,7 @@
   submitted_form.fields[kPasswordFieldIndex].value = ASCIIToUTF16("password");
 
   // Expect no crash.
-  form_manager_->ProvisionallySave(submitted_form, &driver_);
+  form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr);
 }
 
 TEST_F(PasswordFormManagerTest, IsEqualToSubmittedForm) {
@@ -837,7 +850,8 @@
   // No submitted form yet.
   EXPECT_FALSE(form_manager_->IsEqualToSubmittedForm(submitted_form));
 
-  ASSERT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+  ASSERT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
 
   observed_form_.unique_renderer_id += 10;
   observed_form_.fields.clear();
@@ -861,7 +875,8 @@
   submitted_form.fields[kUsernameFieldIndex].value = new_username;
   submitted_form.fields[kPasswordFieldIndex].value = new_password;
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
   EXPECT_TRUE(form_manager_->IsNewLogin());
 
   MockFormSaver& form_saver = MockFormSaver::Get(form_manager_.get());
@@ -910,7 +925,8 @@
   submitted_form.fields[kPasswordFieldIndex].value =
       psl_saved_match_.password_value;
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
   EXPECT_TRUE(form_manager_->IsNewLogin());
   EXPECT_TRUE(form_manager_->IsPendingCredentialsPublicSuffixMatch());
 
@@ -946,7 +962,8 @@
   submitted_form.fields[kUsernameFieldIndex].value = username;
   submitted_form.fields[kPasswordFieldIndex].value = new_password;
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
   EXPECT_FALSE(form_manager_->IsNewLogin());
   EXPECT_TRUE(form_manager_->IsPasswordUpdate());
 
@@ -981,7 +998,8 @@
   base::string16 new_password = saved_match_.password_value + ASCIIToUTF16("1");
   submitted_form.fields[1].value = new_password;
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
   EXPECT_FALSE(form_manager_->IsNewLogin());
   EXPECT_TRUE(form_manager_->IsPasswordUpdate());
 
@@ -1017,7 +1035,8 @@
     auto new_password = saved_match_.password_value + ASCIIToUTF16("1");
     submitted_form.fields[1].value = new_password;
 
-    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+    EXPECT_TRUE(
+        form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
 
     std::map<base::string16, autofill::ServerFieldType> expected_types;
     expected_types[ASCIIToUTF16("password")] = autofill::PASSWORD;
@@ -1047,7 +1066,7 @@
   TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
   fetcher_->NotifyFetchCompleted();
 
-  form_manager_->ProvisionallySave(submitted_form_, &driver_);
+  form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr);
 
   base::string16 new_username =
       parsed_submitted_form_.username_value + ASCIIToUTF16("1");
@@ -1070,7 +1089,7 @@
       ASCIIToUTF16("automatically_chosen_username");
   submitted_form_.fields[0].value = user_chosen_username;
   submitted_form_.fields[1].value = automatically_chosen_username;
-  form_manager_->ProvisionallySave(submitted_form_, &driver_);
+  form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr);
 
   EXPECT_EQ(automatically_chosen_username,
             form_manager_->GetPendingCredentials().username_value);
@@ -1099,7 +1118,7 @@
   TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
   SetNonFederatedAndNotifyFetchCompleted({&saved_match_});
 
-  form_manager_->ProvisionallySave(submitted_form_, &driver_);
+  form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr);
 
   base::string16 new_username = saved_match_.username_value;
   base::string16 expected_password = parsed_submitted_form_.password_value;
@@ -1117,7 +1136,7 @@
   TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
   fetcher_->NotifyFetchCompleted();
 
-  form_manager_->ProvisionallySave(submitted_form_, &driver_);
+  form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr);
 
   base::string16 new_password =
       parsed_submitted_form_.password_value + ASCIIToUTF16("1");
@@ -1145,7 +1164,7 @@
   // Emulate submitting form with known username and different password.
   submitted_form_.fields[kUsernameFieldIndex].value =
       saved_match_.username_value;
-  form_manager_->ProvisionallySave(submitted_form_, &driver_);
+  form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr);
 
   // The user changes password to already saved one.
   base::string16 password = saved_match_.password_value;
@@ -1166,7 +1185,7 @@
   base::string16 pin = ASCIIToUTF16("pin");
   form.fields[0].value = password;
   form.fields[1].value = pin;
-  form_manager_->ProvisionallySave(form, &driver_);
+  form_manager_->ProvisionallySave(form, &driver_, nullptr);
 
   // Check that a second password field is chosen for saving.
   EXPECT_EQ(pin, form_manager_->GetPendingCredentials().password_value);
@@ -1222,7 +1241,8 @@
   fetcher_->NotifyFetchCompleted();
 
   // Provisionally save in order to create pending credentials.
-  ASSERT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  ASSERT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
 
   std::unique_ptr<PasswordFormManager> cloned_manager = form_manager_->Clone();
 
@@ -1313,7 +1333,8 @@
   ukm::TestAutoSetUkmRecorder test_ukm_recorder;
   SetNonFederatedAndNotifyFetchCompleted({&saved_match_});
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
 
   // Destroy the form manager to destroy the UKM recorder it owns. The recorder
   // only records metrics in its destructor.
@@ -1337,7 +1358,8 @@
 
   FormData malformed_form = submitted_form_;
   malformed_form.fields.clear();
-  EXPECT_FALSE(form_manager_->ProvisionallySave(malformed_form, &driver_));
+  EXPECT_FALSE(
+      form_manager_->ProvisionallySave(malformed_form, &driver_, nullptr));
 
   // Destroy the form manager to destroy the UKM recorder it owns. The recorder
   // only records metrics in its destructor.
@@ -1482,7 +1504,8 @@
       .WillOnce(SaveArg<0>(&saved_form));
   EXPECT_CALL(client_, UpdateFormManagers());
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
   form_manager_->Save();
 
   EXPECT_EQ(submitted_form_.fields[kUsernameFieldIndex].value,
@@ -1715,7 +1738,8 @@
   submitted_form.fields[kUsernameFieldIndex].value = username;
   submitted_form.fields[kPasswordFieldIndex].value = new_password;
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
+  EXPECT_TRUE(
+      form_manager_->ProvisionallySave(submitted_form, &driver_, nullptr));
 
   MockFormSaver& form_saver = MockFormSaver::Get(form_manager_.get());
   PasswordForm updated_form;
@@ -1758,7 +1782,7 @@
 
   base::HistogramTester histogram_tester;
   //  Simulate successful submission.
-  form_manager_->ProvisionallySave(submitted_form_, &driver_);
+  form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr);
   form_manager_->GetMetricsRecorder()->LogSubmitPassed();
 
   form_manager_.reset();
@@ -1775,7 +1799,8 @@
     CreateFormManager(observed_form_);
     fetcher_->NotifyFetchCompleted();
 
-    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+    EXPECT_TRUE(
+        form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
 
     if (password_revealed)
       form_manager_->OnPasswordsRevealed();
@@ -1802,7 +1827,8 @@
       form_manager_->SetGenerationPopupWasShown(
           true /*generation_popup_was_shown*/, false /*is_manual_generation*/);
     }
-    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+    EXPECT_TRUE(
+        form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
 
     EXPECT_CALL(
         mock_autofill_download_manager_,
@@ -1827,7 +1853,8 @@
       form_manager_->SetGenerationPopupWasShown(
           true /*generation_popup_was_shown*/, false /*is_manual_generation*/);
     }
-    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+    EXPECT_TRUE(
+        form_manager_->ProvisionallySave(submitted_form_, &driver_, nullptr));
 
     EXPECT_CALL(
         mock_autofill_download_manager_,
@@ -2016,6 +2043,48 @@
 
 #endif  // defined(OS_IOS)
 
+// Tests that username is taken during username first flow.
+TEST_F(PasswordFormManagerTest, UsernameFirstFlow) {
+  TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
+  CreateFormManager(observed_form_only_password_fields_);
+  fetcher_->NotifyFetchCompleted();
+  const base::string16 possible_username = ASCIIToUTF16("possible_username");
+  PossibleUsernameData possible_username_data(
+      saved_match_.signon_realm, 1u /* renderer_id */, possible_username,
+      base::Time::Now());
+
+  FormData submitted_form = observed_form_only_password_fields_;
+  submitted_form.fields[0].value = ASCIIToUTF16("strongpassword");
+
+  ASSERT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_,
+                                               &possible_username_data));
+
+  // Check that a username is chosen from |possible_username_data|.
+  EXPECT_EQ(possible_username,
+            form_manager_->GetPendingCredentials().username_value);
+}
+
+// Tests that username is not taken when a possible username is not valid.
+TEST_F(PasswordFormManagerTest, UsernameFirstFlowDifferentDomains) {
+  TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
+  CreateFormManager(observed_form_only_password_fields_);
+  fetcher_->NotifyFetchCompleted();
+  base::string16 possible_username = ASCIIToUTF16("possible_username");
+  PossibleUsernameData possible_username_data(
+      "https://another.domain.com", 1u /* renderer_id */, possible_username,
+      base::Time::Now());
+
+  FormData submitted_form = observed_form_only_password_fields_;
+  submitted_form.fields[0].value = ASCIIToUTF16("strongpassword");
+
+  ASSERT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_,
+                                               &possible_username_data));
+
+  // |possible_username_data| has different domain then |submitted_form|. Check
+  // that no username is chosen.
+  EXPECT_TRUE(form_manager_->GetPendingCredentials().username_value.empty());
+}
+
 }  // namespace
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index c2c9de7..f65a24c 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -419,11 +419,11 @@
 }
 
 void PasswordManager::OnUserModifiedNonPasswordField(
-    password_manager::PasswordManagerDriver* driver,
+    PasswordManagerDriver* driver,
     int32_t renderer_id,
     const base::string16& value) {
-  // TODO(https://crbug.com/959776): Implemented processing |value| as possible
-  // username for username first flow.
+  possible_username_.emplace(GetSignonRealm(driver->GetLastCommittedURL()),
+                             renderer_id, value, base::Time::Now());
 }
 
 void PasswordManager::ShowManualFallbackForSaving(
@@ -624,8 +624,12 @@
     return nullptr;
   }
 
-  if (!matched_manager->ProvisionallySave(submitted_form, driver))
+  const PossibleUsernameData* possible_username =
+      possible_username_ ? &possible_username_.value() : nullptr;
+  if (!matched_manager->ProvisionallySave(submitted_form, driver,
+                                          possible_username)) {
     return nullptr;
+  }
 
   // Set all other form managers to no submission state.
   for (const auto& manager : form_managers_) {
diff --git a/components/password_manager/core/browser/password_manager.h b/components/password_manager/core/browser/password_manager.h
index 28dbf3f..b08c907 100644
--- a/components/password_manager/core/browser/password_manager.h
+++ b/components/password_manager/core/browser/password_manager.h
@@ -24,6 +24,7 @@
 #include "components/password_manager/core/browser/leak_detection/leak_detection_check_factory.h"
 #include "components/password_manager/core/browser/leak_detection_delegate.h"
 #include "components/password_manager/core/browser/password_manager_metrics_recorder.h"
+#include "components/password_manager/core/browser/possible_username_data.h"
 
 class PrefRegistrySimple;
 
@@ -45,6 +46,7 @@
 class PasswordFormManagerInterface;
 class PasswordManagerMetricsRecorder;
 class PasswordFormManager;
+struct PossibleUsernameData;
 
 // Per-tab password manager. Handles creation and management of UI elements,
 // receiving password form data from the renderer and managing the password
@@ -114,10 +116,9 @@
   // Called when a user changed a value in a non-password field. The field is in
   // a frame corresponding to |driver| and has a renderer id |renderer_id|.
   // |value| is the current value of the field.
-  void OnUserModifiedNonPasswordField(
-      password_manager::PasswordManagerDriver* driver,
-      int32_t renderer_id,
-      const base::string16& value);
+  void OnUserModifiedNonPasswordField(PasswordManagerDriver* driver,
+                                      int32_t renderer_id,
+                                      const base::string16& value);
 
   // Handles a request to show manual fallback for password saving, i.e. the
   // omnibox icon with the anchored hidden prompt.
@@ -340,7 +341,9 @@
 #if !defined(OS_IOS)
   // Helper for making the requests on leak detection.
   LeakDetectionDelegate leak_delegate_;
+
 #endif  // !defined(OS_IOS)
+  base::Optional<PossibleUsernameData> possible_username_;
 
   DISALLOW_COPY_AND_ASSIGN(PasswordManager);
 };
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index d17e9d0..77b2051 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -194,6 +194,7 @@
                void(const autofill::FormsPredictionsMap&));
   MOCK_METHOD0(GetPasswordManager, PasswordManager*());
   MOCK_METHOD0(GetPasswordAutofillManager, PasswordAutofillManager*());
+  MOCK_CONST_METHOD0(GetLastCommittedURL, const GURL&());
 };
 
 // Invokes the password store consumer with a single copy of |form|.
@@ -3281,4 +3282,46 @@
   EXPECT_EQ(password_field_id, form_generation_data.new_password_renderer_id);
 #endif
 }
+
+// Checks that username is saved on username first flow.
+TEST_F(PasswordManagerTest, UsernameFirstFlow) {
+  EXPECT_CALL(*store_, GetLogins(_, _))
+      .WillRepeatedly(WithArg<1>(InvokeEmptyConsumerWithForms()));
+
+  PasswordForm form(MakeSimpleFormWithOnlyPasswordField());
+  // Simulate the user typed a username in username form.
+  const base::string16 username = ASCIIToUTF16("username1");
+  EXPECT_CALL(driver_, GetLastCommittedURL()).WillOnce(ReturnRef(form.origin));
+  manager()->OnUserModifiedNonPasswordField(&driver_, 1001 /* renderer_id */,
+                                            username /* value */);
+
+  // Simulate that a form which contains only 1 field which is password is added
+  // to the page.
+  manager()->OnPasswordFormsParsed(&driver_, {form} /* observed */);
+
+  EXPECT_CALL(client_, IsSavingAndFillingEnabled(form.origin))
+      .WillRepeatedly(Return(true));
+
+  // Simulate that the user typed password and submitted the password form.
+  const base::string16 password = ASCIIToUTF16("uniquepassword");
+  form.form_data.fields[0].value = password;
+  OnPasswordFormSubmitted(form);
+
+  std::unique_ptr<PasswordFormManagerForUI> form_manager_to_save;
+  EXPECT_CALL(client_, PromptUserToSaveOrUpdatePasswordPtr(_))
+      .WillOnce(WithArg<0>(SaveToScopedPtr(&form_manager_to_save)));
+
+  // Simlates successful submission.
+  manager()->OnPasswordFormsRendered(&driver_, {} /* observed */, true);
+
+  // Simulate saving the form, as if the info bar was accepted.
+  PasswordForm saved_form;
+  EXPECT_CALL(*store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved_form));
+  ASSERT_TRUE(form_manager_to_save);
+  form_manager_to_save->Save();
+
+  EXPECT_EQ(username, saved_form.username_value);
+  EXPECT_EQ(password, saved_form.password_value);
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/possible_username_data.cc b/components/password_manager/core/browser/possible_username_data.cc
new file mode 100644
index 0000000..26d3bdb
--- /dev/null
+++ b/components/password_manager/core/browser/possible_username_data.cc
@@ -0,0 +1,49 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/password_manager/core/browser/possible_username_data.h"
+
+#include "base/strings/string_util.h"
+
+using base::char16;
+using base::TimeDelta;
+
+namespace password_manager {
+
+PossibleUsernameData::PossibleUsernameData(std::string signon_realm,
+                                           int32_t renderer_id,
+                                           base::string16 value,
+                                           base::Time last_change)
+    : signon_realm(std::move(signon_realm)),
+      renderer_id(renderer_id),
+      value(std::move(value)),
+      last_change(last_change) {}
+PossibleUsernameData::~PossibleUsernameData() = default;
+
+bool IsPossibleUsernameValid(const PossibleUsernameData& possible_username,
+                             const std::string& submitted_signon_realm,
+                             const base::Time now) {
+  if (submitted_signon_realm != possible_username.signon_realm)
+    return false;
+  // The goal is to avoid false positives in considering which strings might be
+  // username. In the initial version of the username first flow it is better to
+  // be conservative in that.
+  // TODO(https://crbug.com/959776): Reconsider allowing non-ascii symbols in
+  // username for the username first flow.
+  if (!base::IsStringASCII(possible_username.value))
+    return false;
+  for (char16 c : possible_username.value) {
+    if (base::IsUnicodeWhitespace(c))
+      return false;
+  }
+
+  if (now - possible_username.last_change >
+      kMaxDelayBetweenTypingUsernameAndSubmission) {
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace password_manager
diff --git a/components/password_manager/core/browser/possible_username_data.h b/components/password_manager/core/browser/possible_username_data.h
new file mode 100644
index 0000000..eb87b04
--- /dev/null
+++ b/components/password_manager/core/browser/possible_username_data.h
@@ -0,0 +1,47 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_POSSIBLE_USERNAME_DATA_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_POSSIBLE_USERNAME_DATA_H_
+
+#include <string>
+
+#include "base/strings/string16.h"
+#include "base/time/time.h"
+
+namespace password_manager {
+
+// The maximum time between the user typed in a text field and subsequent
+// submission of the password form, such that the typed value is considered to
+// be possible to be username.
+constexpr base::TimeDelta kMaxDelayBetweenTypingUsernameAndSubmission =
+    base::TimeDelta::FromSeconds(60);
+
+// Contains information that the user typed in a text field. It might be the
+// username during username first flow.
+struct PossibleUsernameData {
+  PossibleUsernameData(std::string signon_realm,
+                       int32_t renderer_id,
+                       base::string16 value,
+                       base::Time last_change);
+  ~PossibleUsernameData();
+
+  std::string signon_realm;
+  int32_t renderer_id;
+  base::string16 value;
+  base::Time last_change;
+};
+
+// Checks that |possible_username| might represent an username:
+// 1.|possible_username.signon_realm| == |submitted_signon_realm|
+// 2.|possible_username.value| does not have whitespaces and non-ASCII symbols.
+// 3.|possible_username.value.last_change| was not more than 60 seconds before
+// now.
+bool IsPossibleUsernameValid(const PossibleUsernameData& possible_username,
+                             const std::string& submitted_signon_realm,
+                             const base::Time now);
+
+}  // namespace password_manager
+
+#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_POSSIBLE_USERNAME_DATA_H_
diff --git a/components/password_manager/core/browser/possible_username_data_unittest.cc b/components/password_manager/core/browser/possible_username_data_unittest.cc
new file mode 100644
index 0000000..28039fe1
--- /dev/null
+++ b/components/password_manager/core/browser/possible_username_data_unittest.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 "components/password_manager/core/browser/possible_username_data.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::ASCIIToUTF16;
+using base::Time;
+using base::TimeDelta;
+
+namespace password_manager {
+
+namespace {
+
+class IsPossibleUsernameValidTest : public testing::Test {
+ public:
+  IsPossibleUsernameValidTest()
+      : possible_username_data_(
+            "https://example.com/" /* submitted_signon_realm */,
+            1u /* renderer_id */,
+            ASCIIToUTF16("username") /* value */,
+            base::Time::Now() /* last_change */) {}
+
+ protected:
+  PossibleUsernameData possible_username_data_;
+};
+
+TEST_F(IsPossibleUsernameValidTest, Valid) {
+  EXPECT_TRUE(IsPossibleUsernameValid(possible_username_data_,
+                                      possible_username_data_.signon_realm,
+                                      possible_username_data_.last_change));
+}
+
+// Check that if time delta between last change and submission is more than 60
+// seconds, than data is invalid.
+TEST_F(IsPossibleUsernameValidTest, TimeDeltaBeforeLastChangeAndSubmission) {
+  Time valid_submission_time = possible_username_data_.last_change +
+                               kMaxDelayBetweenTypingUsernameAndSubmission;
+  Time invalid_submission_time =
+      valid_submission_time + TimeDelta::FromSeconds(1);
+  EXPECT_TRUE(IsPossibleUsernameValid(possible_username_data_,
+                                      possible_username_data_.signon_realm,
+                                      valid_submission_time));
+  EXPECT_FALSE(IsPossibleUsernameValid(possible_username_data_,
+                                       possible_username_data_.signon_realm,
+                                       invalid_submission_time));
+}
+
+TEST_F(IsPossibleUsernameValidTest, SignonRealm) {
+  EXPECT_FALSE(IsPossibleUsernameValid(possible_username_data_,
+                                       "https://m.example.com/",
+                                       possible_username_data_.last_change));
+
+  EXPECT_FALSE(IsPossibleUsernameValid(possible_username_data_,
+                                       "https://google.com/",
+                                       possible_username_data_.last_change));
+}
+
+TEST_F(IsPossibleUsernameValidTest, PossibleUsernameValue) {
+  PossibleUsernameData possible_username_data = possible_username_data_;
+
+  // White spaces are not allowed in username.
+  possible_username_data.value = ASCIIToUTF16("user name");
+  EXPECT_FALSE(IsPossibleUsernameValid(possible_username_data,
+                                       possible_username_data.signon_realm,
+                                       possible_username_data.last_change));
+
+  // New lines are not allowed in username.
+  possible_username_data.value = ASCIIToUTF16("user\nname");
+  EXPECT_FALSE(IsPossibleUsernameValid(possible_username_data,
+                                       possible_username_data.signon_realm,
+                                       possible_username_data.last_change));
+
+  // Digits and special characters are ok.
+  possible_username_data.value = ASCIIToUTF16("User_name1234!+&%#\'\"@");
+  EXPECT_TRUE(IsPossibleUsernameValid(possible_username_data,
+                                      possible_username_data.signon_realm,
+                                      possible_username_data.last_change));
+}
+
+}  // namespace
+}  // namespace password_manager
diff --git a/components/password_manager/core/browser/sync_credentials_filter_unittest.cc b/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
index 6f3b5c0..9024e60 100644
--- a/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
+++ b/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
@@ -135,7 +135,7 @@
     fetcher_.SetNonFederated(matches);
     fetcher_.NotifyFetchCompleted();
 
-    form_manager_.ProvisionallySave(pending_.form_data, &driver_);
+    form_manager_.ProvisionallySave(pending_.form_data, &driver_, nullptr);
   }
 
  protected:
diff --git a/components/policy/content/policy_blacklist_navigation_throttle_unittest.cc b/components/policy/content/policy_blacklist_navigation_throttle_unittest.cc
index 43540a4..24c9e3e 100644
--- a/components/policy/content/policy_blacklist_navigation_throttle_unittest.cc
+++ b/components/policy/content/policy_blacklist_navigation_throttle_unittest.cc
@@ -96,7 +96,7 @@
 
   void SetBlacklistUrlPattern(const std::string& pattern) {
     auto value = std::make_unique<base::Value>(base::Value::Type::LIST);
-    value->GetList().push_back(base::Value(pattern));
+    value->Append(base::Value(pattern));
     pref_service_.SetManagedPref(policy::policy_prefs::kUrlBlacklist,
                                  std::move(value));
     base::RunLoop().RunUntilIdle();
@@ -104,7 +104,7 @@
 
   void SetWhitelistUrlPattern(const std::string& pattern) {
     auto value = std::make_unique<base::Value>(base::Value::Type::LIST);
-    value->GetList().push_back(base::Value(pattern));
+    value->Append(base::Value(pattern));
     pref_service_.SetManagedPref(policy::policy_prefs::kUrlWhitelist,
                                  std::move(value));
     base::RunLoop().RunUntilIdle();
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
index 5ed845e..c673919 100644
--- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -1477,7 +1477,7 @@
   event.SetStringPath("foo.prop3", "value3");
 
   base::Value event_list(base::Value::Type::LIST);
-  event_list.GetList().push_back(std::move(event));
+  event_list.Append(std::move(event));
 
   client_->UploadRealtimeReport(
       std::move(policy::RealtimeReportingJobConfiguration::BuildReport(
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.cc b/components/policy/core/common/cloud/cloud_policy_constants.cc
index bdc9cff3..ff3397a9 100644
--- a/components/policy/core/common/cloud/cloud_policy_constants.cc
+++ b/components/policy/core/common/cloud/cloud_policy_constants.cc
@@ -64,6 +64,7 @@
     "device_initial_enrollment_state";
 const char kValueRequestUploadPolicyValidationReport[] =
     "policy_validation_report";
+const char kValueRequestPublicSamlUser[] = "public_saml_user_request";
 
 const char kChromeDevicePolicyType[] = "google/chromeos/device";
 #if defined(OS_CHROMEOS)
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.h b/components/policy/core/common/cloud/cloud_policy_constants.h
index 39cae34..518ece5c 100644
--- a/components/policy/core/common/cloud/cloud_policy_constants.h
+++ b/components/policy/core/common/cloud/cloud_policy_constants.h
@@ -57,6 +57,7 @@
 POLICY_EXPORT extern const char kValueRequestChromeDesktopReport[];
 POLICY_EXPORT extern const char kValueRequestInitialEnrollmentStateRetrieval[];
 POLICY_EXPORT extern const char kValueRequestUploadPolicyValidationReport[];
+POLICY_EXPORT extern const char kValueRequestPublicSamlUser[];
 
 // Policy type strings for the policy_type field in PolicyFetchRequest.
 POLICY_EXPORT extern const char kChromeDevicePolicyType[];
diff --git a/components/policy/core/common/cloud/device_management_service.cc b/components/policy/core/common/cloud/device_management_service.cc
index 0dabcba..0294351e 100644
--- a/components/policy/core/common/cloud/device_management_service.cc
+++ b/components/policy/core/common/cloud/device_management_service.cc
@@ -185,6 +185,8 @@
     case DeviceManagementService::JobConfiguration::
         TYPE_UPLOAD_REAL_TIME_REPORT:
       return "UploadrealtimeReport";
+    case DeviceManagementService::JobConfiguration::TYPE_REQUEST_SAML_URL:
+      return "PublicSamlUserRequest";
   }
   NOTREACHED() << "Invalid job type " << type;
   return "";
diff --git a/components/policy/core/common/cloud/device_management_service.h b/components/policy/core/common/cloud/device_management_service.h
index b2cda39..8a41868 100644
--- a/components/policy/core/common/cloud/device_management_service.h
+++ b/components/policy/core/common/cloud/device_management_service.h
@@ -49,7 +49,7 @@
   // 1..kMaxRetries: number of retries. kMaxRetries is the maximum number of
   // retries allowed, defined in the .cc file.
 
-  // The request failed (too many retries or non-retriable error).
+  // The request failed (too many retries or non-retryable error).
   kRequestFailed = 10,
   // The server responded with an error.
   kRequestError = 11,
@@ -119,7 +119,7 @@
   //
   // JobConfiguration is the interface used by callers to specify parameters
   // of network requests.  This object is not immutable and may be changed after
-  // a call to OnBeforeRetry().  DeviceManagemmentService calls the GetXXX
+  // a call to OnBeforeRetry().  DeviceManagementService calls the GetXXX
   // methods again to create a new network request for each retry.
   //
   // JobControl is the interface used internally by DeviceManagementService to
@@ -163,6 +163,7 @@
       TYPE_INITIAL_ENROLLMENT_STATE_RETRIEVAL = 20,
       TYPE_UPLOAD_POLICY_VALIDATION_REPORT = 21,
       TYPE_UPLOAD_REAL_TIME_REPORT = 22,
+      TYPE_REQUEST_SAML_URL = 23,
     };
 
     // The set of HTTP query parmaters of the request.
@@ -350,7 +351,7 @@
 
  protected:
   // Adds the query parameter to the network request's URL.  If the parameter
-  // already eixsts its value is replaced.
+  // already exists its value is replaced.
   void AddParameter(const std::string& name, const std::string& value);
 
   const DMAuth& GetAuth() { return *auth_data_.get(); }
@@ -379,7 +380,7 @@
   // and |oauth_token_| can be specified for one request.
   base::Optional<std::string> oauth_token_;
 
-  // Query pamaters for the network request.
+  // Query parameters for the network request.
   ParameterMap query_params_;
 
   DISALLOW_COPY_AND_ASSIGN(JobConfigurationBase);
diff --git a/components/policy/core/common/cloud/dmserver_job_configurations.cc b/components/policy/core/common/cloud/dmserver_job_configurations.cc
index dcf95fde..bb6e6d4 100644
--- a/components/policy/core/common/cloud/dmserver_job_configurations.cc
+++ b/components/policy/core/common/cloud/dmserver_job_configurations.cc
@@ -76,6 +76,8 @@
     case DeviceManagementService::JobConfiguration::
         TYPE_UPLOAD_POLICY_VALIDATION_REPORT:
       return dm_protocol::kValueRequestUploadPolicyValidationReport;
+    case DeviceManagementService::JobConfiguration::TYPE_REQUEST_SAML_URL:
+      return dm_protocol::kValueRequestPublicSamlUser;
     case DeviceManagementService::JobConfiguration::
         TYPE_UPLOAD_REAL_TIME_REPORT:
       NOTREACHED() << "Not a DMServer request type" << type;
diff --git a/components/policy/core/common/policy_merger.cc b/components/policy/core/common/policy_merger.cc
index c931bc5..bf5b236 100644
--- a/components/policy/core/common/policy_merger.cc
+++ b/components/policy/core/common/policy_merger.cc
@@ -117,7 +117,7 @@
   if (value_changed) {
     base::ListValue* new_value = new base::ListValue();
     for (const base::Value* it : merged_values)
-      new_value->GetList().emplace_back(it->Clone());
+      new_value->Append(it->Clone());
 
     policy->value.reset(new_value);
   }
diff --git a/components/policy/core/common/policy_service_impl_unittest.cc b/components/policy/core/common/policy_service_impl_unittest.cc
index 4cd96e0..2ccd9f09 100644
--- a/components/policy/core/common/policy_service_impl_unittest.cc
+++ b/components/policy/core/common/policy_service_impl_unittest.cc
@@ -783,8 +783,7 @@
 
   std::unique_ptr<base::Value> policy =
       std::make_unique<base::Value>(base::Value::Type::LIST);
-  policy->GetList().push_back(
-      base::Value(policy::key::kContentPackManualBehaviorURLs));
+  policy->Append(base::Value(policy::key::kContentPackManualBehaviorURLs));
 
   auto policy_bundle1 = std::make_unique<PolicyBundle>();
   PolicyMap& policy_map1 = policy_bundle1->Get(chrome_namespace);
@@ -828,19 +827,18 @@
   const PolicyNamespace chrome_namespace(POLICY_DOMAIN_CHROME, std::string());
 
   std::unique_ptr<base::ListValue> list1 = std::make_unique<base::ListValue>();
-  list1->GetList().push_back(base::Value("google.com"));
-  list1->GetList().push_back(base::Value("gmail.com"));
+  list1->Append(base::Value("google.com"));
+  list1->Append(base::Value("gmail.com"));
   std::unique_ptr<base::ListValue> list2 = std::make_unique<base::ListValue>();
-  list2->GetList().push_back(base::Value("example.com"));
-  list2->GetList().push_back(base::Value("gmail.com"));
+  list2->Append(base::Value("example.com"));
+  list2->Append(base::Value("gmail.com"));
   std::unique_ptr<base::ListValue> result = std::make_unique<base::ListValue>();
-  result->GetList().push_back(base::Value("google.com"));
-  result->GetList().push_back(base::Value("gmail.com"));
-  result->GetList().push_back(base::Value("example.com"));
+  result->Append(base::Value("google.com"));
+  result->Append(base::Value("gmail.com"));
+  result->Append(base::Value("example.com"));
 
   std::unique_ptr<base::ListValue> policy = std::make_unique<base::ListValue>();
-  policy->GetList().push_back(
-      base::Value(policy::key::kExtensionInstallForcelist));
+  policy->Append(base::Value(policy::key::kExtensionInstallForcelist));
 
   auto policy_bundle1 = std::make_unique<PolicyBundle>();
   PolicyMap& policy_map1 = policy_bundle1->Get(chrome_namespace);
@@ -883,20 +881,18 @@
   const PolicyNamespace chrome_namespace(POLICY_DOMAIN_CHROME, std::string());
 
   std::unique_ptr<base::ListValue> list1 = std::make_unique<base::ListValue>();
-  list1->GetList().push_back(base::Value("google.com"));
+  list1->Append(base::Value("google.com"));
   std::unique_ptr<base::ListValue> list2 = std::make_unique<base::ListValue>();
-  list2->GetList().push_back(base::Value("example.com"));
+  list2->Append(base::Value("example.com"));
   std::unique_ptr<base::ListValue> list3 = std::make_unique<base::ListValue>();
-  list3->GetList().push_back(base::Value("example_xyz.com"));
+  list3->Append(base::Value("example_xyz.com"));
   std::unique_ptr<base::ListValue> result = std::make_unique<base::ListValue>();
-  result->GetList().push_back(base::Value("google.com"));
-  result->GetList().push_back(base::Value("example.com"));
+  result->Append(base::Value("google.com"));
+  result->Append(base::Value("example.com"));
 
   std::unique_ptr<base::ListValue> policy = std::make_unique<base::ListValue>();
-  policy->GetList().push_back(
-      base::Value(policy::key::kExtensionInstallForcelist));
-  policy->GetList().push_back(
-      base::Value(policy::key::kExtensionInstallBlacklist));
+  policy->Append(base::Value(policy::key::kExtensionInstallForcelist));
+  policy->Append(base::Value(policy::key::kExtensionInstallBlacklist));
 
   auto policy_bundle1 = std::make_unique<PolicyBundle>();
   PolicyMap& policy_map1 = policy_bundle1->Get(chrome_namespace);
@@ -953,20 +949,18 @@
   const PolicyNamespace chrome_namespace(POLICY_DOMAIN_CHROME, std::string());
 
   std::unique_ptr<base::ListValue> list1 = std::make_unique<base::ListValue>();
-  list1->GetList().push_back(base::Value("google.com"));
+  list1->Append(base::Value("google.com"));
   std::unique_ptr<base::ListValue> list2 = std::make_unique<base::ListValue>();
-  list2->GetList().push_back(base::Value("example.com"));
+  list2->Append(base::Value("example.com"));
   std::unique_ptr<base::ListValue> list3 = std::make_unique<base::ListValue>();
-  list3->GetList().push_back(base::Value("example_xyz.com"));
+  list3->Append(base::Value("example_xyz.com"));
   std::unique_ptr<base::ListValue> result = std::make_unique<base::ListValue>();
-  result->GetList().push_back(base::Value("google.com"));
-  result->GetList().push_back(base::Value("example.com"));
+  result->Append(base::Value("google.com"));
+  result->Append(base::Value("example.com"));
 
   std::unique_ptr<base::ListValue> policy = std::make_unique<base::ListValue>();
-  policy->GetList().push_back(
-      base::Value(policy::key::kExtensionInstallForcelist));
-  policy->GetList().push_back(
-      base::Value(policy::key::kExtensionInstallBlacklist));
+  policy->Append(base::Value(policy::key::kExtensionInstallForcelist));
+  policy->Append(base::Value(policy::key::kExtensionInstallBlacklist));
 
   auto policy_bundle1 = std::make_unique<PolicyBundle>();
   PolicyMap& policy_map1 = policy_bundle1->Get(chrome_namespace);
diff --git a/components/policy/core/common/schema_unittest.cc b/components/policy/core/common/schema_unittest.cc
index bb79daa..d65815b 100644
--- a/components/policy/core/common/schema_unittest.cc
+++ b/components/policy/core/common/schema_unittest.cc
@@ -711,8 +711,8 @@
     dict.SetString("one", "string");
     dict.SetInteger("two", 2);
     base::ListValue list;
-    list.GetList().push_back(dict.Clone());
-    list.GetList().push_back(std::move(dict));
+    list.Append(dict.Clone());
+    list.Append(std::move(dict));
     bundle.SetKey("ArrayOfObjects", std::move(list));
   }
 
@@ -721,8 +721,8 @@
     list.AppendString("a string");
     list.AppendString("another string");
     base::ListValue listlist;
-    listlist.GetList().push_back(list.Clone());
-    listlist.GetList().push_back(std::move(list));
+    listlist.Append(list.Clone());
+    listlist.Append(std::move(list));
     bundle.SetKey("ArrayOfArray", std::move(listlist));
   }
 
@@ -1332,7 +1332,7 @@
   base::DictionaryValue object;
   object.SetKey("objectProperty", base::Value(true));
   base::ListValue array;
-  array.GetList().push_back(base::Value(true));
+  array.Append(base::Value(true));
 
   base::Value value(base::Value::Type::DICTIONARY);
   value.SetKey(kNormalBooleanSchema, base::Value(true));
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto
index 5039a3aa..26d16b03 100644
--- a/components/policy/proto/chrome_device_policy.proto
+++ b/components/policy/proto/chrome_device_policy.proto
@@ -1343,8 +1343,16 @@
   optional bool device_powerwash_allowed = 1;
 }
 
+// Settings that controls which devices are whitelisted for certain urls to be
+// used via the WebUSB API on the login screen.
+message DeviceLoginScreenWebUsbAllowDevicesForUrlsProto {
+  // This is a JSON string, for details see
+  // "DeviceLoginScreenWebUsbAllowDevicesForUrls" in policy_templates.json.
+  optional string device_login_screen_webusb_allow_devices_for_urls = 1;
+}
+
 message ChromeDeviceSettingsProto {
-  reserved 61;
+  reserved 61, 90;
   optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1;
   optional UserWhitelistProto user_whitelist = 2;
   optional GuestModeEnabledProto guest_mode_enabled = 3;
@@ -1455,4 +1463,6 @@
   optional DeviceUsbPowerShareProto device_usb_power_share = 88;
   optional DeviceScheduledUpdateCheckProto device_scheduled_update_check = 89;
   optional DevicePowerwashAllowedProto device_powerwash_allowed = 91;
+  optional DeviceLoginScreenWebUsbAllowDevicesForUrlsProto
+      device_login_screen_webusb_allow_devices_for_urls = 92;
 }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 1dd6288..8d0f27b 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -4951,6 +4951,52 @@
         URL patterns in this policy should not clash with the ones configured via WebUsbBlockedForUrls. If there is a clash, this policy will take precedence over WebUsbBlockedForUrls and WebUsbAskForUrls.''',
     },
     {
+      'name': 'DeviceLoginScreenWebUsbAllowDevicesForUrls',
+      'owners': ['reillyg@chromium.org', 'odejesush@chromium.org'],
+      'type': 'dict',
+      'schema': {
+        'type': 'array',
+        'items': {
+          'type': 'object',
+          'properties': {
+            'devices': {
+              'type': 'array',
+              'items': {
+                'type': 'object',
+                'properties': {
+                  'vendor_id': { 'type': 'integer' },
+                  'product_id': { 'type': 'integer' }
+                }
+              }
+            },
+            'urls': {
+              'type': 'array',
+              'items': { 'type': 'string' }
+            }
+          },
+          'required': ['devices', 'urls']
+        }
+      },
+      'supported_on': ['chrome_os:79-'],
+      'device_only': True,
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': False,
+      },
+      'example_value': [{
+        'devices': [{'vendor_id': 1234, 'product_id': 5678}],
+        'urls': ['https://google.com', 'https://requesting.com,https://embedded.com'],
+      }],
+      'id': 603,
+      'caption': '''Automatically grant permission to these sites to connect to USB devices with the given vendor and product IDs on the login screen.''',
+      'tags': ['website-sharing'],
+      'desc': '''Allows you to set a list of urls that specify which sites will automatically be granted permission to access a USB device with the given vendor and product IDs on the login screen. Each item in the list must contain both devices and urls in order for the policy to be valid. Each item in devices can contain a vendor ID and product ID field. Any ID that is omitted is treated as a wildcard with one exception, and that exception is that a product ID cannot be specified without a vendor ID also being specified. Otherwise, the policy will not be valid and will be ignored.
+
+        The USB permission model uses the URL of the requesting site ("requesting URL") and the URL of the top-level frame site ("embedding URL") to grant permission to the requesting URL to access the USB device. The requesting URL may be different than the embedding URL when the requesting site is loaded in an iframe. Therefore, the "urls" field can contain up to two URL strings delimited by a comma to specify the requesting and embedding URL respectively. If only one URL is specified, then access to the corresponding USB devices will be granted when the requesting site's URL matches this URL regardless of embedding status. The URLs in "urls" must be valid URLs, otherwise the policy will be ignored.
+
+        If this policy is left not set, the global default value will be used for all sites (no automatic access).''',
+    },
+    {
       'name': 'WebUsbAskForUrls',
       'owners': ['reillyg@chromium.org', 'odejesush@chromium.org'],
       'type': 'list',
@@ -15170,7 +15216,11 @@
       'desc': '''
       If the policy is set to true, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is allowed to collect WebRTC event logs from Google services (e.g. Google Meet), and upload those logs to Google.
 
-      If the policy is set to false, or is unset, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> may not collect nor upload such logs.
+      If the policy is set to false, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> may not collect nor upload such logs.
+
+      If the policy is unset, up to and including M76, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> may not collect nor upload such logs.
+
+      If the policy is unset, since M77, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> may collect or upload such logs by default if the browser profile is considered managed, i.e. if the profile receives cloud or machine level policies, and is not a child, ephemeral, login, or incognito profile.
 
       These logs contain diagnostic information helpful when debugging issues with audio or video calls in Chrome, such as the time and size of sent and received RTP packets, feedback about congestion on the network, and metadata about time and quality of audio and video frames. These logs do not contain audio or video contents from the call.
 
@@ -17785,7 +17835,7 @@
     },
     'doc_reference_link': {
       'desc': '''Text pointing the user to the reference page for this policy, which may have more info (since it doesn't have a size limit)''',
-      'text': '''Reference: <ph name="REFERENCE_URL">$6<ex>https://www.chromium.org/administrators/policy-list-3#WallpaperImage</ex></ph>''',
+      'text': '''Reference: <ph name="REFERENCE_URL">$6<ex>https://cloud.google.com/docs/chrome-enterprise/policies/?policy=WallpaperImage</ex></ph>''',
     },
     'doc_legacy_single_line_label': {
       'desc': '''A label for the legacy single-line textbox for a policy also has a more user-friendly multi-line textbox. See http://crbug/829328''',
@@ -17805,7 +17855,7 @@
     },
     'doc_schema_description_link': {
       'desc': '''Text pointing the user to the expanded documentation page for this policy, containing the information about schema and formatting.''',
-      'text': '''See <ph name="REFERENCE_URL">$6<ex>https://www.chromium.org/administrators/policy-list-3#WallpaperImage</ex></ph> for more information about schema and formatting.'''
+      'text': '''See <ph name="REFERENCE_URL">$6<ex>https://cloud.google.com/docs/chrome-enterprise/policies/?policy=WallpaperImage</ex></ph> for more information about schema and formatting.'''
     },
     'deprecated_policy_group_caption': {
       'desc': '''Localized name for the deprecated policies folder, for Microsoft's Group Policy Editor.''',
@@ -17977,7 +18027,8 @@
     'DeviceBatteryChargeCustomStartCharging': 'device_battery_charge_mode.custom_charge_start',
     'DeviceBatteryChargeCustomStopCharging': 'device_battery_charge_mode.custom_charge_stop',
     'DeviceScheduledUpdateCheck': 'device_scheduled_update_check.device_scheduled_update_check_settings',
-    'DevicePowerwashAllowed': 'device_powerwash_allowed.device_powerwash_allowed'
+    'DevicePowerwashAllowed': 'device_powerwash_allowed.device_powerwash_allowed',
+    'DeviceLoginScreenWebUsbAllowDevicesForUrls': 'device_login_screen_webusb_allow_devices_for_urls.device_login_screen_webusb_allow_devices_for_urls'
   },
   'policy_atomic_group_definitions': [
     {
@@ -18164,6 +18215,7 @@
       'caption': '''Web USB settings''',
       'policies': [
         'DefaultWebUsbGuardSetting',
+        'DeviceLoginScreenWebUsbAllowDevicesForUrls',
         'WebUsbAllowDevicesForUrls',
         'WebUsbAskForUrls',
         'WebUsbBlockedForUrls',
@@ -18418,6 +18470,6 @@
   ],
   'placeholders': [],
   'deleted_policy_ids': [412, 546, 562, 569],
-  'highest_id_currently_used': 602,
+  'highest_id_currently_used': 603,
   'highest_atomic_group_id_currently_used': 37
 }
diff --git a/components/policy/test_support/local_policy_test_server.cc b/components/policy/test_support/local_policy_test_server.cc
index 986ab47..84647e0 100644
--- a/components/policy/test_support/local_policy_test_server.cc
+++ b/components/policy/test_support/local_policy_test_server.cc
@@ -131,7 +131,7 @@
   client_dict.SetKey(kClientStateKeyDeviceToken, base::Value(dm_token));
   base::Value state_keys_value(base::Value::Type::LIST);
   for (const auto& key : state_keys) {
-    state_keys_value.GetList().push_back(base::Value(
+    state_keys_value.Append(base::Value(
         base::ToLowerASCII(base::HexEncode(key.data(), key.size()))));
   }
   client_dict.SetKey(kClientStateKeyStateKeys, std::move(state_keys_value));
@@ -142,15 +142,13 @@
 
   // Allow all policy types for now.
   base::Value types(base::Value::Type::LIST);
-  types.GetList().emplace_back(dm_protocol::kChromeDevicePolicyType);
-  types.GetList().emplace_back(dm_protocol::kChromeUserPolicyType);
-  types.GetList().emplace_back(dm_protocol::kChromePublicAccountPolicyType);
-  types.GetList().emplace_back(dm_protocol::kChromeExtensionPolicyType);
-  types.GetList().emplace_back(dm_protocol::kChromeSigninExtensionPolicyType);
-  types.GetList().emplace_back(
-      dm_protocol::kChromeMachineLevelUserCloudPolicyType);
-  types.GetList().emplace_back(
-      dm_protocol::kChromeMachineLevelExtensionCloudPolicyType);
+  types.Append(dm_protocol::kChromeDevicePolicyType);
+  types.Append(dm_protocol::kChromeUserPolicyType);
+  types.Append(dm_protocol::kChromePublicAccountPolicyType);
+  types.Append(dm_protocol::kChromeExtensionPolicyType);
+  types.Append(dm_protocol::kChromeSigninExtensionPolicyType);
+  types.Append(dm_protocol::kChromeMachineLevelUserCloudPolicyType);
+  types.Append(dm_protocol::kChromeMachineLevelExtensionCloudPolicyType);
 
   client_dict.SetKey(kClientStateKeyAllowedPolicyTypes, std::move(types));
   clients_.SetKey(dm_token, std::move(client_dict));
diff --git a/components/policy/tools/template_writers/writers/adm_writer.py b/components/policy/tools/template_writers/writers/adm_writer.py
index 6af5e1d..f15c13f 100755
--- a/components/policy/tools/template_writers/writers/adm_writer.py
+++ b/components/policy/tools/template_writers/writers/adm_writer.py
@@ -7,7 +7,7 @@
 import re
 
 NEWLINE = '\r\n'
-POLICY_LIST_URL = '''https://www.chromium.org/administrators/policy-list-3'''
+POLICY_LIST_URL = '''https://cloud.google.com/docs/chrome-enterprise/policies/?policy='''
 
 
 def GetWriter(config):
@@ -181,7 +181,7 @@
     Includes a link to the relevant documentation on chromium.org.
     '''
     policy_desc = policy.get('desc')
-    reference_url = POLICY_LIST_URL + '#' + policy['name']
+    reference_url = POLICY_LIST_URL + policy['name']
     reference_link_text = self.GetLocalizedMessage('reference_link')
     reference_link_text = reference_link_text.replace('$6', reference_url)
 
diff --git a/components/policy/tools/template_writers/writers/adm_writer_unittest.py b/components/policy/tools/template_writers/writers/adm_writer_unittest.py
index adf28950..9e25d313 100755
--- a/components/policy/tools/template_writers/writers/adm_writer_unittest.py
+++ b/components/policy/tools/template_writers/writers/adm_writer_unittest.py
@@ -193,7 +193,8 @@
 googlechrome_recommended="Google Chrome - Recommended"
 MainPolicy_Policy="Caption of main."
 MainPolicy_Explain="Description of main.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#MainPolicy"''')
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=MainPolicy"''')
     self.CompareOutputs(output, expected_output)
 
   def testMainPolicyRecommendedOnly(self):
@@ -252,7 +253,8 @@
 googlechrome_recommended="Google Chrome - Recommended"
 MainPolicy_Policy="Caption of main."
 MainPolicy_Explain="Description of main.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#MainPolicy"''')
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=MainPolicy"''')
     self.CompareOutputs(output, expected_output)
 
   def testStringPolicy(self):
@@ -318,7 +320,8 @@
 chromium_recommended="Chromium - Recommended"
 StringPolicy_Policy="Caption of policy."
 StringPolicy_Explain="Description of group.\\nWith a newline.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#StringPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=StringPolicy"
 StringPolicy_Part="Caption of policy."
 ''')
     self.CompareOutputs(output, expected_output)
@@ -385,7 +388,8 @@
 chromium_recommended="Chromium - Recommended"
 IntPolicy_Policy="Caption of policy."
 IntPolicy_Explain="Description of policy.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#IntPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=IntPolicy"
 IntPolicy_Part="Caption of policy."
 ''')
     self.CompareOutputs(output, expected_output)
@@ -453,7 +457,8 @@
 chromium_recommended="Chromium - Recommended"
 IntPolicy_Policy="Caption of policy."
 IntPolicy_Explain="Description of policy.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#IntPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=IntPolicy"
 IntPolicy_Part="Caption of policy."
 ''')
     self.CompareOutputs(output, expected_output)
@@ -543,7 +548,8 @@
 googlechrome_recommended="Google Chrome - Recommended"
 EnumPolicy_Policy="Caption of policy."
 EnumPolicy_Explain="Description of policy.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#EnumPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=EnumPolicy"
 EnumPolicy_Part="Caption of policy."
 ProxyServerDisabled_DropDown="Option1"
 ProxyServerAutoDetect_DropDown="Option2"
@@ -629,7 +635,8 @@
 googlechrome_recommended="Google Chrome - Recommended"
 EnumPolicy_Policy="Caption of policy."
 EnumPolicy_Explain="Description of policy.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#EnumPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=EnumPolicy"
 EnumPolicy_Part="Caption of policy."
 ProxyServerDisabled_DropDown="Option1"
 ProxyServerAutoDetect_DropDown="Option2"
@@ -700,7 +707,8 @@
 chromium_recommended="Chromium - Recommended"
 ListPolicy_Policy="Caption of list policy."
 ListPolicy_Explain="Description of list policy.\\nWith a newline.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#ListPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ListPolicy"
 ListPolicy_Part="Label of list policy."
 ''')
     self.CompareOutputs(output, expected_output)
@@ -775,7 +783,8 @@
 chromium_recommended="Chromium - Recommended"
 ListPolicy_Policy="Caption of list policy."
 ListPolicy_Explain="Description of list policy.\\nWith a newline.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#ListPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ListPolicy"
 ListPolicy_Part="Label of list policy."
 ''')
     self.CompareOutputs(output, expected_output)
@@ -842,8 +851,8 @@
 chromium_recommended="Chromium - Recommended"
 DictionaryPolicy_Policy="Caption of policy."
 DictionaryPolicy_Explain="Description of group.\\n\\n\
-Reference: https://www.chromium.org/administrators/\
-policy-list-3#DictionaryPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=DictionaryPolicy"
 DictionaryPolicy_Part="Caption of policy."
 ''')
     self.CompareOutputs(output, expected_output)
@@ -910,7 +919,8 @@
 chromium_recommended="Chromium - Recommended"
 ExternalPolicy_Policy="Caption of policy."
 ExternalPolicy_Explain="Description of group.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#ExternalPolicy"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalPolicy"
 ExternalPolicy_Part="Caption of policy."
 ''')
     self.CompareOutputs(output, expected_output)
@@ -1013,7 +1023,8 @@
 googlechrome_recommended="Google Chrome - Recommended"
 MainPolicy_Policy="Caption of main."
 MainPolicy_Explain="Description of main.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#MainPolicy"''')
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=MainPolicy"''')
     self.CompareOutputs(output, expected_output)
 
   def testPolicyGroup(self):
@@ -1113,11 +1124,13 @@
 Group1_Category="Caption of group."
 Policy1_Policy="Caption of policy1."
 Policy1_Explain="Description of policy1.\\nWith a newline.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#Policy1"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=Policy1"
 Policy1_Part="Caption of policy1."
 Policy2_Policy="Caption of policy2."
 Policy2_Explain="Description of policy2.\\nWith a newline.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#Policy2"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=Policy2"
 Policy2_Part="Caption of policy2."
 ''')
     self.CompareOutputs(output, expected_output)
@@ -1206,12 +1219,14 @@
 googlechrome_recommended="Google Chrome - Recommended"
 EnumPolicy_A_Policy="Caption of policy A."
 EnumPolicy_A_Explain="Description of policy A.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#EnumPolicy.A"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=EnumPolicy.A"
 EnumPolicy_A_Part="Caption of policy A."
 tls1_2_DropDown="tls1.2"
 EnumPolicy_B_Policy="Caption of policy B."
 EnumPolicy_B_Explain="Description of policy B.\\n\\n\
-Reference: https://www.chromium.org/administrators/policy-list-3#EnumPolicy.B"
+Reference: \
+https://cloud.google.com/docs/chrome-enterprise/policies/?policy=EnumPolicy.B"
 EnumPolicy_B_Part="Caption of policy B."
 ''')
     self.CompareOutputs(output, expected_output)
diff --git a/components/policy/tools/template_writers/writers/adml_writer_unittest.py b/components/policy/tools/template_writers/writers/adml_writer_unittest.py
index a9448ff..29e4dc7 100755
--- a/components/policy/tools/template_writers/writers/adml_writer_unittest.py
+++ b/components/policy/tools/template_writers/writers/adml_writer_unittest.py
@@ -429,7 +429,7 @@
         '<string id="DictionaryPolicyStub">Dictionary policy caption</string>\n'
         '<string id="DictionaryPolicyStub_Explain">'
         'This is a test description.\n'
-        'See https://www.chromium.org/administrators/policy-list-3#'
+        'See https://cloud.google.com/docs/chrome-enterprise/policies/?policy='
         'DictionaryPolicyStub\n</string>')
     self.AssertXMLEquals(output, expected_output)
     # Assert generated presentation elements.
diff --git a/components/policy/tools/template_writers/writers/chromeos_adml_writer_unittest.py b/components/policy/tools/template_writers/writers/chromeos_adml_writer_unittest.py
index a6cc580..5def539b 100755
--- a/components/policy/tools/template_writers/writers/chromeos_adml_writer_unittest.py
+++ b/components/policy/tools/template_writers/writers/chromeos_adml_writer_unittest.py
@@ -87,7 +87,7 @@
         '<string id="DictionaryPolicyStub">Dictionary policy caption</string>\n'
         '<string id="DictionaryPolicyStub_Explain">'
         'This is a test description.\n'
-        'See https://www.chromium.org/administrators/policy-list-3#'
+        'See https://cloud.google.com/docs/chrome-enterprise/policies/?policy='
         'DictionaryPolicyStub\n</string>\n'
         '<string id="DictionaryPolicyStub_Legacy">'
         'Dictionary policy label (deprecated)</string>')
diff --git a/components/policy/tools/template_writers/writers/json_writer_unittest.py b/components/policy/tools/template_writers/writers/json_writer_unittest.py
index 1f712787..3dacf25 100755
--- a/components/policy/tools/template_writers/writers/json_writer_unittest.py
+++ b/components/policy/tools/template_writers/writers/json_writer_unittest.py
@@ -350,8 +350,8 @@
     expected_output = (
         TEMPLATE_HEADER + '  // Example Dictionary Policy\n' + HEADER_DELIMETER
         + '  // Example Dictionary Policy See '
-        'https://www.chromium.org/administrators\n'
-        '  // /policy-list-3#DictionaryPolicy\n\n'
+        'https://cloud.google.com/docs/chrome-\n'
+        '  // enterprise/policies/?policy=DictionaryPolicy\n\n'
         '  //"DictionaryPolicy": {"bool": true, "dict": {"a": 1, '
         '"b": 2}, "int": 10, "list": [1, 2, 3], "string": "abc"}\n\n'
         '}')
@@ -383,8 +383,8 @@
     expected_output = (
         TEMPLATE_HEADER + '  // Example External Policy\n' + HEADER_DELIMETER +
         '  // Example External Policy See '
-        'https://www.chromium.org/administrators/policy-\n'
-        '  // list-3#ExternalPolicy\n\n'
+        'https://cloud.google.com/docs/chrome-\n'
+        '  // enterprise/policies/?policy=ExternalPolicy\n\n'
         '  //"ExternalPolicy": {"hash": "deadbeef", "url": "https://example.com/avatar.jpg"}\n\n'
         '}')
     self.CompareOutputs(output, expected_output)
diff --git a/components/policy/tools/template_writers/writers/template_writer.py b/components/policy/tools/template_writers/writers/template_writer.py
index d883355..390eb27 100755
--- a/components/policy/tools/template_writers/writers/template_writer.py
+++ b/components/policy/tools/template_writers/writers/template_writer.py
@@ -400,6 +400,6 @@
       url = policy['url_schema']
     if (policy['type'] in ('dict', 'external') or
         'validation_schema' in policy or 'description_schema' in policy):
-      url = 'https://www.chromium.org/administrators/policy-list-3#' + policy[
-          'name']
+      url = ('https://cloud.google.com/docs/chrome-enterprise/policies/?policy='
+             + policy['name'])
     return schema_description_link_text.replace('$6', url) if url else ''
diff --git a/components/policy/tools/template_writers/writers/template_writer_unittest.py b/components/policy/tools/template_writers/writers/template_writer_unittest.py
index 8e06df3..fd051d1 100755
--- a/components/policy/tools/template_writers/writers/template_writer_unittest.py
+++ b/components/policy/tools/template_writers/writers/template_writer_unittest.py
@@ -228,7 +228,8 @@
     expanded_description = tw.GetExpandedPolicyDescription(policy)
     self.assertEqual(
         expanded_description,
-        'See https://www.chromium.org/administrators/policy-list-3#PolicyName')
+        'See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=PolicyName'
+    )
 
 
 if __name__ == '__main__':
diff --git a/components/printing/test/print_render_frame_helper_browsertest.cc b/components/printing/test/print_render_frame_helper_browsertest.cc
index b52ad1f..32995cdf 100644
--- a/components/printing/test/print_render_frame_helper_browsertest.cc
+++ b/components/printing/test/print_render_frame_helper_browsertest.cc
@@ -1155,7 +1155,7 @@
   page_range.SetKey(kSettingPageRangeFrom, base::Value(2));
   page_range.SetKey(kSettingPageRangeTo, base::Value(3));
   base::Value page_range_array(base::Value::Type::LIST);
-  page_range_array.GetList().push_back(std::move(page_range));
+  page_range_array.Append(std::move(page_range));
   dict.SetKey(kSettingPageRange, std::move(page_range_array));
 
   OnPrintPreview(dict);
diff --git a/components/safe_browsing/browser/safe_browsing_network_context.cc b/components/safe_browsing/browser/safe_browsing_network_context.cc
index 713f202..bafff4a2 100644
--- a/components/safe_browsing/browser/safe_browsing_network_context.cc
+++ b/components/safe_browsing/browser/safe_browsing_network_context.cc
@@ -16,6 +16,7 @@
 #include "content/public/browser/network_context_client_base.h"
 #include "content/public/browser/network_service_instance.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "net/net_buildflags.h"
 #include "services/network/network_context.h"
@@ -41,9 +42,11 @@
 
   network::mojom::NetworkContext* GetNetworkContext() {
     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-    if (!network_context_ || network_context_.encountered_error()) {
+    if (!network_context_ || !network_context_.is_connected()) {
+      network_context_.reset();
       content::GetNetworkService()->CreateNetworkContext(
-          MakeRequest(&network_context_), CreateNetworkContextParams());
+          network_context_.BindNewPipeAndPassReceiver(),
+          CreateNetworkContextParams());
 
       mojo::PendingRemote<network::mojom::NetworkContextClient> client_remote;
       mojo::MakeSelfOwnedReceiver(
@@ -128,7 +131,7 @@
 
   base::FilePath user_data_dir_;
   NetworkContextParamsFactory network_context_params_factory_;
-  network::mojom::NetworkContextPtr network_context_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_;
   network::mojom::URLLoaderFactoryPtr url_loader_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SharedURLLoaderFactory);
diff --git a/components/safe_browsing/common/safe_browsing_prefs.cc b/components/safe_browsing/common/safe_browsing_prefs.cc
index 01c693b..5228057 100644
--- a/components/safe_browsing/common/safe_browsing_prefs.cc
+++ b/components/safe_browsing/common/safe_browsing_prefs.cc
@@ -293,10 +293,9 @@
   // Add the status of the preferences if they are Enabled or Disabled for the
   // user.
   for (const char* preference : safe_browsing_preferences) {
-    preferences_list.GetList().push_back(base::Value(preference));
+    preferences_list.Append(base::Value(preference));
     bool enabled = prefs->GetBoolean(preference);
-    preferences_list.GetList().push_back(
-        base::Value(enabled ? "Enabled" : "Disabled"));
+    preferences_list.Append(base::Value(enabled ? "Enabled" : "Disabled"));
   }
   return preferences_list;
 }
diff --git a/components/safe_browsing/features.cc b/components/safe_browsing/features.cc
index 2c1c99c..f507c9b 100644
--- a/components/safe_browsing/features.cc
+++ b/components/safe_browsing/features.cc
@@ -113,11 +113,11 @@
 // Adds the name and the enabled/disabled status of a given feature.
 void AddFeatureAndAvailability(const base::Feature* exp_feature,
                                base::ListValue* param_list) {
-  param_list->GetList().push_back(base::Value(exp_feature->name));
+  param_list->Append(base::Value(exp_feature->name));
   if (base::FeatureList::IsEnabled(*exp_feature)) {
-    param_list->GetList().push_back(base::Value("Enabled"));
+    param_list->Append(base::Value("Enabled"));
   } else {
-    param_list->GetList().push_back(base::Value("Disabled"));
+    param_list->Append(base::Value("Disabled"));
   }
 }
 }  // namespace
diff --git a/components/safe_browsing/triggers/trigger_throttler.cc b/components/safe_browsing/triggers/trigger_throttler.cc
index 480d011..e22bf9b 100644
--- a/components/safe_browsing/triggers/trigger_throttler.cc
+++ b/components/safe_browsing/triggers/trigger_throttler.cc
@@ -251,7 +251,7 @@
         base::NumberToString(static_cast<int>(trigger_item.first)),
         base::Value(base::Value::Type::LIST));
     for (const base::Time timestamp : trigger_item.second) {
-      pref_timestamps->GetList().push_back(base::Value(timestamp.ToDoubleT()));
+      pref_timestamps->Append(base::Value(timestamp.ToDoubleT()));
     }
   }
 
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.cc b/components/safe_browsing/web_ui/safe_browsing_ui.cc
index 57a812b..fe951b82 100644
--- a/components/safe_browsing/web_ui/safe_browsing_ui.cc
+++ b/components/safe_browsing/web_ui/safe_browsing_ui.cc
@@ -254,10 +254,9 @@
 void AddStoreInfo(const DatabaseManagerInfo::DatabaseInfo::StoreInfo store_info,
                   base::ListValue* database_info_list) {
   if (store_info.has_file_name()) {
-    database_info_list->GetList().push_back(
-        base::Value(store_info.file_name()));
+    database_info_list->Append(base::Value(store_info.file_name()));
   } else {
-    database_info_list->GetList().push_back(base::Value("Unknown store"));
+    database_info_list->Append(base::Value("Unknown store"));
   }
 
   std::string store_info_string = "<blockquote>";
@@ -287,15 +286,14 @@
 
   store_info_string += "</blockquote>";
 
-  database_info_list->GetList().push_back(base::Value(store_info_string));
+  database_info_list->Append(base::Value(store_info_string));
 }
 
 void AddDatabaseInfo(const DatabaseManagerInfo::DatabaseInfo database_info,
                      base::ListValue* database_info_list) {
   if (database_info.has_database_size_bytes()) {
-    database_info_list->GetList().push_back(
-        base::Value("Database size (in bytes)"));
-    database_info_list->GetList().push_back(
+    database_info_list->Append(base::Value("Database size (in bytes)"));
+    database_info_list->Append(
         base::Value(static_cast<double>(database_info.database_size_bytes())));
   }
 
@@ -309,22 +307,18 @@
                    base::ListValue* database_info_list) {
   if (update_info.has_network_status_code()) {
     // Network status of the last GetUpdate().
-    database_info_list->GetList().push_back(
-        base::Value("Last update network status code"));
-    database_info_list->GetList().push_back(
-        base::Value(update_info.network_status_code()));
+    database_info_list->Append(base::Value("Last update network status code"));
+    database_info_list->Append(base::Value(update_info.network_status_code()));
   }
   if (update_info.has_last_update_time_millis()) {
-    database_info_list->GetList().push_back(base::Value("Last update time"));
-    database_info_list->GetList().push_back(
-        UserReadableTimeFromMillisSinceEpoch(
-            update_info.last_update_time_millis()));
+    database_info_list->Append(base::Value("Last update time"));
+    database_info_list->Append(UserReadableTimeFromMillisSinceEpoch(
+        update_info.last_update_time_millis()));
   }
   if (update_info.has_next_update_time_millis()) {
-    database_info_list->GetList().push_back(base::Value("Next update time"));
-    database_info_list->GetList().push_back(
-        UserReadableTimeFromMillisSinceEpoch(
-            update_info.next_update_time_millis()));
+    database_info_list->Append(base::Value("Next update time"));
+    database_info_list->Append(UserReadableTimeFromMillisSinceEpoch(
+        update_info.next_update_time_millis()));
   }
 }
 
@@ -379,13 +373,13 @@
             .GetString());
   }
 
-  full_hash_cache_list->GetList().push_back(std::move(full_hash_cache_parsed));
+  full_hash_cache_list->Append(std::move(full_hash_cache_parsed));
 
   for (auto full_hash_info_it :
        full_hash_cache.cached_hash_prefix_info().full_hash_info()) {
     base::DictionaryValue full_hash_info_dict;
     ParseFullHashInfo(full_hash_info_it, &full_hash_info_dict);
-    full_hash_cache_list->GetList().push_back(std::move(full_hash_info_dict));
+    full_hash_cache_list->Append(std::move(full_hash_info_dict));
   }
 }
 
@@ -395,14 +389,14 @@
     base::DictionaryValue number_of_hits;
     number_of_hits.SetInteger("Number of cache hits",
                               full_hash_cache_info_proto.number_of_hits());
-    full_hash_cache_info->GetList().push_back(std::move(number_of_hits));
+    full_hash_cache_info->Append(std::move(number_of_hits));
   }
 
   // Record FullHashCache list.
   for (auto full_hash_cache_it : full_hash_cache_info_proto.full_hash_cache()) {
     base::ListValue full_hash_cache_list;
     ParseFullHashCache(full_hash_cache_it, &full_hash_cache_list);
-    full_hash_cache_info->GetList().push_back(std::move(full_hash_cache_list));
+    full_hash_cache_info->Append(std::move(full_hash_cache_list));
   }
 }
 
@@ -458,7 +452,7 @@
 
   base::ListValue ip_addresses;
   for (const std::string& ip_address : referrer.ip_addresses()) {
-    ip_addresses.GetList().push_back(base::Value(ip_address));
+    ip_addresses.Append(base::Value(ip_address));
   }
   referrer_dict.SetKey("ip_addresses", std::move(ip_addresses));
 
@@ -476,7 +470,7 @@
   base::ListValue server_redirects;
   for (const ReferrerChainEntry::ServerRedirect& server_redirect :
        referrer.server_redirect_chain()) {
-    server_redirects.GetList().push_back(base::Value(server_redirect.url()));
+    server_redirects.Append(base::Value(server_redirect.url()));
   }
   referrer_dict.SetKey("server_redirect_chain", std::move(server_redirects));
 
@@ -542,8 +536,7 @@
 
   auto referrer_chain = std::make_unique<base::ListValue>();
   for (const auto& referrer_chain_entry : cdr.referrer_chain()) {
-    referrer_chain->GetList().push_back(
-        SerializeReferrer(referrer_chain_entry));
+    referrer_chain->Append(SerializeReferrer(referrer_chain_entry));
   }
   dict.SetList("referrer_chain", std::move(referrer_chain));
 
@@ -822,7 +815,7 @@
 
   base::ListValue referrer_list;
   for (const ReferrerChainEntry& referrer : frame.referrer_chain()) {
-    referrer_list.GetList().push_back(SerializeReferrer(referrer));
+    referrer_list.Append(SerializeReferrer(referrer));
   }
   frame_dict.SetKey("referrer_chain", std::move(referrer_list));
 
@@ -837,7 +830,7 @@
     form_dict.SetKey("action_url", base::Value(form.action_url()));
     form_dict.SetKey("has_password_field",
                      base::Value(form.has_password_field()));
-    form_list.GetList().push_back(std::move(form_dict));
+    form_list.Append(std::move(form_dict));
   }
   frame_dict.SetKey("forms", std::move(form_list));
 
@@ -850,7 +843,7 @@
 
   base::ListValue domains_list;
   for (const std::string& domain : event.domains_matching_password()) {
-    domains_list.GetList().push_back(base::Value(domain));
+    domains_list.Append(base::Value(domain));
   }
   event_dict.SetKey("domains_matching_password", std::move(domains_list));
 
@@ -919,7 +912,7 @@
 
   base::ListValue finch_list;
   for (const std::string& finch_group : population.finch_active_groups()) {
-    finch_list.GetList().push_back(base::Value(finch_group));
+    finch_list.Append(base::Value(finch_group));
   }
   population_dict.SetKey("finch_active_groups", std::move(finch_list));
 
@@ -992,7 +985,7 @@
 
   base::ListValue frames_list;
   for (const LoginReputationClientRequest::Frame& frame : request.frames()) {
-    frames_list.GetList().push_back(SerializeFrame(frame));
+    frames_list.Append(SerializeFrame(frame));
   }
   request_dict.SetKey("frames", std::move(frames_list));
 
@@ -1154,8 +1147,8 @@
   }
 
   base::Value response(base::Value::Type::LIST);
-  response.GetList().push_back(base::Value(cookie));
-  response.GetList().push_back(base::Value(time));
+  response.Append(base::Value(cookie));
+  response.Append(base::Value(time));
 
   AllowJavascript();
   ResolveJavascriptCallback(base::Value(callback_id), std::move(response));
@@ -1201,7 +1194,7 @@
                       &database_manager_info);
     }
 
-    database_manager_info.GetList().push_back(
+    database_manager_info.Append(
         base::Value(AddFullHashCacheInfo(full_hash_cache_info_proto)));
   }
 #endif
@@ -1221,8 +1214,7 @@
   base::ListValue cdrs_sent;
 
   for (const auto& cdr : cdrs) {
-    cdrs_sent.GetList().push_back(
-        base::Value(SerializeClientDownloadRequest(*cdr)));
+    cdrs_sent.Append(base::Value(SerializeClientDownloadRequest(*cdr)));
   }
 
   AllowJavascript();
@@ -1239,8 +1231,7 @@
   base::ListValue cdrs_received;
 
   for (const auto& cdr : cdrs) {
-    cdrs_received.GetList().push_back(
-        base::Value(SerializeClientDownloadResponse(*cdr)));
+    cdrs_received.Append(base::Value(SerializeClientDownloadResponse(*cdr)));
   }
 
   AllowJavascript();
@@ -1256,7 +1247,7 @@
   base::ListValue sent_reports;
 
   for (const auto& report : reports) {
-    sent_reports.GetList().push_back(base::Value(SerializeCSBRR(*report)));
+    sent_reports.Append(base::Value(SerializeCSBRR(*report)));
   }
 
   AllowJavascript();
@@ -1272,7 +1263,7 @@
   base::ListValue events_sent;
 
   for (const sync_pb::UserEventSpecifics& event : events)
-    events_sent.GetList().push_back(SerializePGEvent(event));
+    events_sent.Append(SerializePGEvent(event));
 
   AllowJavascript();
   std::string callback_id;
@@ -1287,7 +1278,7 @@
   base::ListValue events_sent;
 
   for (const sync_pb::GaiaPasswordReuse& event : events)
-    events_sent.GetList().push_back(SerializeSecurityEvent(event));
+    events_sent.Append(SerializeSecurityEvent(event));
 
   AllowJavascript();
   std::string callback_id;
@@ -1303,10 +1294,9 @@
   for (size_t request_index = 0; request_index < requests.size();
        request_index++) {
     base::ListValue ping_entry;
-    ping_entry.GetList().push_back(base::Value(int(request_index)));
-    ping_entry.GetList().push_back(
-        base::Value(SerializePGPing(requests[request_index])));
-    pings_sent.GetList().push_back(std::move(ping_entry));
+    ping_entry.Append(base::Value(int(request_index)));
+    ping_entry.Append(base::Value(SerializePGPing(requests[request_index])));
+    pings_sent.Append(std::move(ping_entry));
   }
 
   AllowJavascript();
@@ -1322,10 +1312,10 @@
   base::ListValue responses_sent;
   for (const auto& token_and_response : responses) {
     base::ListValue response_entry;
-    response_entry.GetList().push_back(base::Value(token_and_response.first));
-    response_entry.GetList().push_back(
+    response_entry.Append(base::Value(token_and_response.first));
+    response_entry.Append(
         base::Value(SerializePGResponse(token_and_response.second)));
-    responses_sent.GetList().push_back(std::move(response_entry));
+    responses_sent.Append(std::move(response_entry));
   }
 
   AllowJavascript();
@@ -1356,7 +1346,7 @@
 
   base::ListValue referrer_list;
   for (const ReferrerChainEntry& entry : referrer_chain) {
-    referrer_list.GetList().push_back(SerializeReferrer(entry));
+    referrer_list.Append(SerializeReferrer(entry));
   }
 
   std::string referrer_chain_serialized;
@@ -1375,7 +1365,7 @@
 
   base::ListValue messages_received;
   for (const auto& message : log_messages) {
-    messages_received.GetList().push_back(
+    messages_received.Append(
         base::Value(SerializeLogMessage(message.first, message.second)));
   }
 
@@ -1423,8 +1413,8 @@
     int token,
     const LoginReputationClientRequest& request) {
   base::ListValue request_list;
-  request_list.GetList().push_back(base::Value(token));
-  request_list.GetList().push_back(base::Value(SerializePGPing(request)));
+  request_list.Append(base::Value(token));
+  request_list.Append(base::Value(SerializePGPing(request)));
 
   AllowJavascript();
   FireWebUIListener("pg-pings-update", request_list);
@@ -1434,8 +1424,8 @@
     int token,
     const LoginReputationClientResponse& response) {
   base::ListValue response_list;
-  response_list.GetList().push_back(base::Value(token));
-  response_list.GetList().push_back(base::Value(SerializePGResponse(response)));
+  response_list.Append(base::Value(token));
+  response_list.Append(base::Value(SerializePGResponse(response)));
 
   AllowJavascript();
   FireWebUIListener("pg-responses-update", response_list);
diff --git a/components/security_interstitials/core/browser/resources/interstitial_large.js b/components/security_interstitials/core/browser/resources/interstitial_large.js
index d0b2968..3b0b0c7 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_large.js
+++ b/components/security_interstitials/core/browser/resources/interstitial_large.js
@@ -71,6 +71,7 @@
   var lookalike = interstitialType == 'LOOKALIKE';
   var billing = interstitialType == 'SAFEBROWSING' &&
                     loadTimeData.getBoolean('billing');
+  var originPolicy = interstitialType == "ORIGIN_POLICY";
   var hidePrimaryButton = loadTimeData.getBoolean('hide_primary_button');
   var showRecurrentErrorParagraph = loadTimeData.getBoolean(
     'show_recurrent_error_paragraph');
@@ -80,7 +81,7 @@
     $('body').classList.add('dark-mode-available');
   }
 
-  if (ssl) {
+  if (ssl || originPolicy) {
     $('body').classList.add(badClock ? 'bad-clock' : 'ssl');
     $('error-code').textContent = loadTimeData.getString('errorCode');
     $('error-code').classList.remove(HIDDEN_CLASS);
diff --git a/components/security_interstitials_strings.grdp b/components/security_interstitials_strings.grdp
index bafe7d71..09613421 100644
--- a/components/security_interstitials_strings.grdp
+++ b/components/security_interstitials_strings.grdp
@@ -408,13 +408,12 @@
   </message>
   <message name="IDS_ORIGIN_POLICY_HEADING"
     desc="The large heading at the top of the Origin Policy Error Interstitial">
-    Blocked according to <ph name="ORIGIN">$2</ph>'s security policy.
+    Blocked according to <ph name="ORIGIN">$2</ph>'s origin policy.
   </message>
   <message name="IDS_ORIGIN_POLICY_INFO"
     desc="The primary explanatory paragraph for the Origin Policy Error interstitial.">
-    The site <ph name="ORIGIN">$2</ph> has requested that a security policy
-    will apply to all its request, and this policy presently deems the site
-    unsafe.
+    The site <ph name="ORIGIN">$2</ph> has requested that an origin policy
+    will apply to all its request, but this policy cannot presently be applied.
   </message>
   <message name="IDS_ORIGIN_POLICY_INFO2" desc="The second paragrpah of the text of the Origin Policy Error Interstitial. (Presently intentionally left blank.)" />
   <message name="IDS_ORIGIN_POLICY_BUTTON"
@@ -427,25 +426,29 @@
   </message>
   <message name="IDS_ORIGIN_POLICY_EXPLANATION_CANNOT_LOAD" desc="The text of the Origin Policy Error Interstitial that will be displayed when the user presses the 'Advanced' button for additional information, for the case where the policy could not be loaded.">
     The server you are going to, <ph name="ORIGIN">$2</ph>, has requested that
-    a security policy will be applied to all requests to it. But it has now
+    an origin policy will be applied to all requests to it. But it has now
     failed to deliver a policy, which prevents the browser from fulfilling
-    your request for <ph name="SITE">$1</ph>.
+    your request for <ph name="SITE">$1</ph>. Origin policies can be used by
+    site operators to configure security and other properties for a site.
   </message>
   <message name="IDS_ORIGIN_POLICY_EXPLANATION_SHOULD_NOT_REDIRECT" desc="The text of the Origin Policy Error Interstitial that will be displayed when the user presses the 'Advanced' button for additional information, for the case where the policy request was met with a 'redirect' response.">
     The server you are going to, <ph name="ORIGIN">$2</ph>, has requested that
-    a security policy will be applied to all requests to it. But instead of
+    an origin policy will be applied to all requests to it. But instead of
     delivering a policy it has redirected the browser elsewhere, which prevents
-    the browser from fulfilling your request for <ph name="SITE">$1</ph>.
+    the browser from fulfilling your request for <ph name="SITE">$1</ph>. Origin
+    policies can be used by site operators to configure security and other
+    properties for a site.
   </message>
   <message name="IDS_ORIGIN_POLICY_EXPLANATION_OTHER" desc="The text of the Origin Policy Error Interstitial that will be displayed when the user presses the 'Advanced' button for additional information, for cases other than redirect or load error.">
     The server you are going to, <ph name="ORIGIN">$2</ph>, has requested that
-    a security policy will be applied to all requests to it. But it has now
-    delivered an invalid policy, which prevents the browser from
-    fulfilling your request for <ph name="SITE">$1</ph>.
+    an origin policy will be applied to all requests to it. But it has now
+    delivered an invalid policy, which means the browser cannot fullfil your
+    request for <ph name="SITE">$1</ph>. Origin policies can be used by
+    site operators to configure security and other properties for a site.
   </message>
   <message name="IDS_ORIGIN_POLICY_FINAL_PARAGRAPH"
     desc="The text of the Origin Policy Error Interstitial that a user can click to proceed to the site, despite the error.">
-    <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>Proceed to <ph name="SITE">$1<ex>example.com</ex></ph> (unsafe)<ph name="END_LINK">&lt;/a&gt;</ph>
+    <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>Proceed to <ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_LINK">&lt;/a&gt;</ph>
   </message>
   <message name="IDS_ORIGIN_POLICY_CLOSE" desc="The text of the Origin Policy Error Interstitial that will hide the 'advanced' section again.">
     Hide advanced
diff --git a/components/signin/internal/identity_manager/android/BUILD.gn b/components/signin/internal/identity_manager/android/BUILD.gn
index d9b022f..4b51665 100644
--- a/components/signin/internal/identity_manager/android/BUILD.gn
+++ b/components/signin/internal/identity_manager/android/BUILD.gn
@@ -3,7 +3,9 @@
 generate_jni("jni_headers") {
   namespace = "signin"
   sources = [
+    "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java",
     "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java",
     "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java",
+    "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java",
   ]
 }
diff --git a/components/signin/public/identity_manager/BUILD.gn b/components/signin/public/identity_manager/BUILD.gn
index 149b8c4..6d2a0b9 100644
--- a/components/signin/public/identity_manager/BUILD.gn
+++ b/components/signin/public/identity_manager/BUILD.gn
@@ -2,6 +2,10 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+if (is_android) {
+  import("//build/config/android/rules.gni")
+}
+
 source_set("identity_manager") {
   sources = [
     "access_token_fetcher.cc",
@@ -25,6 +29,7 @@
     "load_credentials_state.h",
     "primary_account_access_token_fetcher.cc",
     "primary_account_access_token_fetcher.h",
+    "primary_account_mutator.cc",
     "primary_account_mutator.h",
     "set_accounts_in_cookie_result.h",
     "ubertoken_fetcher.cc",
@@ -71,6 +76,14 @@
   ]
 }
 
+if (is_android) {
+  java_cpp_enum("identity_manager_enum_javagen") {
+    sources = [
+      "primary_account_mutator.h",
+    ]
+  }
+}
+
 source_set("unit_tests") {
   testonly = true
 
diff --git a/components/signin/public/identity_manager/account_info.cc b/components/signin/public/identity_manager/account_info.cc
index 94350088..424852d1 100644
--- a/components/signin/public/identity_manager/account_info.cc
+++ b/components/signin/public/identity_manager/account_info.cc
@@ -7,6 +7,7 @@
 
 #if defined(OS_ANDROID)
 #include "base/android/jni_string.h"
+#include "components/signin/internal/identity_manager/android/jni_headers/CoreAccountId_jni.h"
 #include "components/signin/internal/identity_manager/android/jni_headers/CoreAccountInfo_jni.h"
 #endif
 
@@ -127,13 +128,28 @@
 
 #if defined(OS_ANDROID)
 base::android::ScopedJavaLocalRef<jobject> ConvertToJavaCoreAccountInfo(
+    JNIEnv* env,
     const CoreAccountInfo& account_info) {
-  if (account_info.IsEmpty())
-    return base::android::ScopedJavaLocalRef<jobject>();
-  JNIEnv* env = base::android::AttachCurrentThread();
   return signin::Java_CoreAccountInfo_Constructor(
-      env,
-      base::android::ConvertUTF8ToJavaString(env, account_info.account_id.id),
-      base::android::ConvertUTF8ToJavaString(env, account_info.email));
+      env, ConvertToJavaCoreAccountId(env, account_info.account_id),
+      base::android::ConvertUTF8ToJavaString(env, account_info.email),
+      base::android::ConvertUTF8ToJavaString(env, account_info.gaia));
+}
+
+base::android::ScopedJavaLocalRef<jobject> ConvertToJavaCoreAccountId(
+    JNIEnv* env,
+    const CoreAccountId& account_id) {
+  DCHECK(!account_id.empty());
+  return signin::Java_CoreAccountId_Constructor(
+      env, base::android::ConvertUTF8ToJavaString(env, account_id.id));
+}
+
+CoreAccountId ConvertFromJavaCoreAccountId(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_core_account_id) {
+  CoreAccountId id;
+  id.id = base::android::ConvertJavaStringToUTF8(
+      signin::Java_CoreAccountId_getId(env, j_core_account_id));
+  return id;
 }
 #endif
diff --git a/components/signin/public/identity_manager/account_info.h b/components/signin/public/identity_manager/account_info.h
index c5b0359..91ae337b 100644
--- a/components/signin/public/identity_manager/account_info.h
+++ b/components/signin/public/identity_manager/account_info.h
@@ -82,7 +82,18 @@
 #if defined(OS_ANDROID)
 // Constructs a Java CoreAccountInfo from the provided C++ CoreAccountInfo
 base::android::ScopedJavaLocalRef<jobject> ConvertToJavaCoreAccountInfo(
+    JNIEnv* env,
     const CoreAccountInfo& account_info);
+
+// Constructs a Java CoreAccountId from the provided C++ CoreAccountId
+base::android::ScopedJavaLocalRef<jobject> ConvertToJavaCoreAccountId(
+    JNIEnv* env,
+    const CoreAccountId& account_id);
+
+// Constructs a C++ CoreAccountId from the provided java CoreAccountId
+CoreAccountId ConvertFromJavaCoreAccountId(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_core_account_id);
 #endif
 
 #endif  // COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_ACCOUNT_INFO_H_
diff --git a/components/signin/public/identity_manager/android/BUILD.gn b/components/signin/public/identity_manager/android/BUILD.gn
index 2c422f4..9e837218 100644
--- a/components/signin/public/identity_manager/android/BUILD.gn
+++ b/components/signin/public/identity_manager/android/BUILD.gn
@@ -9,13 +9,16 @@
     "//third_party/android_deps:com_android_support_support_annotations_java",
   ]
 
-  srcjar_deps =
-      [ "//components/signin/public/base:signin_metrics_enum_javagen" ]
+  srcjar_deps = [
+    "//components/signin/public/base:signin_metrics_enum_javagen",
+    "//components/signin/public/identity_manager:identity_manager_enum_javagen",
+  ]
 
   java_files = [
-    "java/src/org/chromium/components/signin/identitymanager/IdentityManager.java",
     "java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java",
     "java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java",
+    "java/src/org/chromium/components/signin/identitymanager/IdentityManager.java",
+    "java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java",
   ]
 
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
diff --git a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java
index e690e4a..6351803 100644
--- a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java
+++ b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java
@@ -6,46 +6,44 @@
 
 import android.support.annotation.NonNull;
 
+import org.chromium.base.annotations.CalledByNative;
+
 /**
- * A wrapper around Gaia ID that represents a stable account identifier.
- *
- * This wrapper helps to make sure that code using accounts doesn't accidentally use account name in
- * place of Gaia ID and vice versa.
- *
+ * Represents the id of an account, which can be either a Gaia ID or email depending on the
+ * migration status within AccountTrackerService.
  * This class has a native counterpart called CoreAccountId.
  */
 public class CoreAccountId {
-    private final String mGaiaId;
+    private final String mId;
 
     /**
-     * Constructs a new CoreAccountId from a String representation of Gaia ID.
+     * Constructs a new CoreAccountId from a String representation of the account ID.
      */
-    public CoreAccountId(@NonNull String gaiaId) {
-        assert gaiaId != null;
-        // Check that a user email is not used by mistake.
-        assert !gaiaId.contains("@");
-
-        mGaiaId = gaiaId;
+    @CalledByNative
+    public CoreAccountId(@NonNull String id) {
+        assert id != null;
+        mId = id;
     }
 
-    public String getGaiaIdAsString() {
-        return mGaiaId;
+    @CalledByNative
+    public String getId() {
+        return mId;
     }
 
     @Override
     public String toString() {
-        return mGaiaId;
+        return mId;
     }
 
     @Override
     public int hashCode() {
-        return mGaiaId.hashCode();
+        return mId.hashCode();
     }
 
     @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof CoreAccountId)) return false;
         CoreAccountId other = (CoreAccountId) obj;
-        return mGaiaId.equals(other.mGaiaId);
+        return mId.equals(other.mId);
     }
 }
diff --git a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java
index cbb28e2..41f17c5 100644
--- a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java
+++ b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java
@@ -17,8 +17,6 @@
  *
  * This class has a native counterpart called CoreAccountInfo. There are several differences between
  * these two classes:
- * - Android class doesn't store Gaia ID as a string because {@link CoreAccountId} already contains
- * it.
  * - Android class additionally exposes {@link android.accounts.Account} object for interactions
  * with the system.
  * - Android class has the "account name" whereas the native class has "email". This is the same
@@ -27,21 +25,38 @@
 public class CoreAccountInfo {
     private final CoreAccountId mId;
     private final Account mAccount;
+    private final String mGaiaId;
 
-    public CoreAccountInfo(@NonNull CoreAccountId id, @NonNull Account account) {
+    /**
+     * Constructs a CoreAccountInfo with the provided parameters
+     * @param id A CoreAccountId associated with the account, equal to either account.name or
+     *         gaiaId.
+     * @param account Android account.
+     * @param gaiaId String representation of the Gaia ID. Must not be an email address.
+     */
+    public CoreAccountInfo(
+            @NonNull CoreAccountId id, @NonNull Account account, @NonNull String gaiaId) {
         assert id != null;
         assert account != null;
+        assert gaiaId != null;
+        assert !gaiaId.contains("@");
 
         mId = id;
         mAccount = account;
+        mGaiaId = gaiaId;
     }
 
     @CalledByNative
-    private CoreAccountInfo(@NonNull String id, @NonNull String name) {
+    private CoreAccountInfo(
+            @NonNull CoreAccountId id, @NonNull String name, @NonNull String gaiaId) {
         assert id != null;
         assert name != null;
+        assert gaiaId != null;
+        assert !gaiaId.contains("@");
+
+        mId = id;
         mAccount = AccountManagerFacade.createAccountFromName(name);
-        mId = new CoreAccountId(id);
+        mGaiaId = gaiaId;
     }
 
     /**
@@ -59,6 +74,13 @@
     }
 
     /**
+     * Returns the string representation of the Gaia ID
+     */
+    public String getGaiaId() {
+        return mGaiaId;
+    }
+
+    /**
      * Returns {@link android.accounts.Account} object holding a name of the current account.
      */
     public Account getAccount() {
diff --git a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
index 53e6722..d61aa8c5 100644
--- a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
+++ b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
@@ -4,6 +4,8 @@
 
 package org.chromium.components.signin.identitymanager;
 
+import android.support.annotation.Nullable;
+
 import org.chromium.base.ObserverList;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
@@ -35,21 +37,27 @@
     }
 
     private long mNativeIdentityManager;
+    private PrimaryAccountMutator mPrimaryAccountMutator;
 
     private final ObserverList<Observer> mObservers = new ObserverList<>();
 
     /**
      * Called by native to create an instance of IdentityManager.
+     * @param primaryAccountMutator can be null if native's IdentityManager received a null
+     * PrimaryAccountMutator, this happens in tests.
      */
     @CalledByNative
-    static private IdentityManager create(long nativeIdentityManager) {
+    static private IdentityManager create(
+            long nativeIdentityManager, @Nullable PrimaryAccountMutator primaryAccountMutator) {
         assert nativeIdentityManager != 0;
-        return new IdentityManager(nativeIdentityManager);
+        return new IdentityManager(nativeIdentityManager, primaryAccountMutator);
     }
 
     @VisibleForTesting
-    public IdentityManager(long nativeIdentityManager) {
+    public IdentityManager(
+            long nativeIdentityManager, PrimaryAccountMutator primaryAccountMutator) {
         mNativeIdentityManager = nativeIdentityManager;
+        mPrimaryAccountMutator = primaryAccountMutator;
     }
 
     /**
@@ -102,8 +110,30 @@
         return IdentityManagerJni.get().hasPrimaryAccount(mNativeIdentityManager);
     }
 
+    /**
+     * Looks up and returns information for account with given |email_address|. If the account
+     * cannot be found, return a null value.
+     */
+    public @Nullable CoreAccountInfo
+    findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(String email) {
+        return IdentityManagerJni.get()
+                .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
+                        mNativeIdentityManager, email);
+    }
+
+    /*
+     * Returns pointer to the object used to change the signed-in state of the
+     * primary account.
+     */
+    public PrimaryAccountMutator getPrimaryAccountMutator() {
+        return mPrimaryAccountMutator;
+    }
+
     @NativeMethods
     interface Natives {
         public boolean hasPrimaryAccount(long nativeIdentityManager);
+        public @Nullable CoreAccountInfo
+        findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
+                long nativeIdentityManager, String email);
     }
 }
diff --git a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java
new file mode 100644
index 0000000..5a8b8ce
--- /dev/null
+++ b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java
@@ -0,0 +1,57 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.signin.identitymanager;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.NativeMethods;
+import org.chromium.components.signin.metrics.SignoutDelete;
+import org.chromium.components.signin.metrics.SignoutReason;
+
+/**
+ * PrimaryAccountMutator is the interface to set and clear the primary account (see IdentityManager
+ * for more information).
+ */
+public class PrimaryAccountMutator {
+    private static final String TAG = "PrimaryAccountMuta";
+
+    private final long mNativePrimaryAccountMutator;
+
+    @CalledByNative
+    private PrimaryAccountMutator(long nativePrimaryAccountMutator) {
+        assert nativePrimaryAccountMutator != 0;
+        mNativePrimaryAccountMutator = nativePrimaryAccountMutator;
+    }
+
+    /**
+     * Marks the account with |account_id| as the primary account, and returns whether the operation
+     * succeeded or not. To succeed, this requires that:
+     *   - the account is known by the IdentityManager.
+     *   - setting the primary account is allowed,
+     *   - the account username is allowed by policy,
+     *   - there is not already a primary account set.
+     */
+    public boolean setPrimaryAccount(CoreAccountId accountId) {
+        return PrimaryAccountMutatorJni.get().setPrimaryAccount(
+                mNativePrimaryAccountMutator, accountId);
+    }
+
+    /**
+     * Clears the primary account, and returns whether the operation succeeded or not. Depending on
+     * |action|, the other accounts known to the IdentityManager may be deleted.
+     */
+    public boolean clearPrimaryAccount(@ClearAccountsAction int action,
+            @SignoutReason int sourceMetric, @SignoutDelete int deleteMetric) {
+        return PrimaryAccountMutatorJni.get().clearPrimaryAccount(
+                mNativePrimaryAccountMutator, action, sourceMetric, deleteMetric);
+    }
+
+    @NativeMethods
+    interface Natives {
+        public boolean setPrimaryAccount(long nativePrimaryAccountMutator, CoreAccountId accountId);
+        public boolean clearPrimaryAccount(long nativePrimaryAccountMutator,
+                @ClearAccountsAction int action, @SignoutReason int sourceMetric,
+                @SignoutDelete int deleteMetric);
+    }
+}
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc
index 4e42032..d5a87f55 100644
--- a/components/signin/public/identity_manager/identity_manager.cc
+++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -105,8 +105,12 @@
     UpdateUnconsentedPrimaryAccount();
 
 #if defined(OS_ANDROID)
+  base::android::ScopedJavaLocalRef<jobject> java_primary_account_mutator =
+      primary_account_mutator_ ? primary_account_mutator_->GetJavaObject()
+                               : nullptr;
   java_identity_manager_ = Java_IdentityManager_create(
-      base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this));
+      base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this),
+      java_primary_account_mutator);
 #endif
 }
 
@@ -435,6 +439,18 @@
 bool IdentityManager::HasPrimaryAccount(JNIEnv* env) const {
   return HasPrimaryAccount();
 }
+
+base::android::ScopedJavaLocalRef<jobject> IdentityManager::
+    FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
+        JNIEnv* env,
+        const base::android::JavaParamRef<jstring>& j_email) const {
+  auto account_info =
+      FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
+          base::android::ConvertJavaStringToUTF8(env, j_email));
+  if (!account_info.has_value())
+    return nullptr;
+  return ConvertToJavaCoreAccountInfo(env, account_info.value());
+}
 #endif
 
 PrimaryAccountManager* IdentityManager::GetPrimaryAccountManager() {
@@ -516,10 +532,12 @@
     observer.OnPrimaryAccountSet(account_info);
   }
 #if defined(OS_ANDROID)
-  if (java_identity_manager_)
+  if (java_identity_manager_) {
+    JNIEnv* env = base::android::AttachCurrentThread();
     Java_IdentityManager_onPrimaryAccountSet(
-        base::android::AttachCurrentThread(), java_identity_manager_,
-        ConvertToJavaCoreAccountInfo(account_info));
+        env, java_identity_manager_,
+        ConvertToJavaCoreAccountInfo(env, account_info));
+  }
 #endif
 }
 
@@ -530,10 +548,12 @@
     observer.OnPrimaryAccountCleared(account_info);
   }
 #if defined(OS_ANDROID)
-  if (java_identity_manager_)
+  if (java_identity_manager_) {
+    JNIEnv* env = base::android::AttachCurrentThread();
     Java_IdentityManager_onPrimaryAccountCleared(
-        base::android::AttachCurrentThread(), java_identity_manager_,
-        ConvertToJavaCoreAccountInfo(account_info));
+        env, java_identity_manager_,
+        ConvertToJavaCoreAccountInfo(env, account_info));
+  }
 #endif
 }
 
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h
index c8a09931..8e56dd3 100644
--- a/components/signin/public/identity_manager/identity_manager.h
+++ b/components/signin/public/identity_manager/identity_manager.h
@@ -459,6 +459,11 @@
 
   // Overloads for calls from java:
   bool HasPrimaryAccount(JNIEnv* env) const;
+
+  base::android::ScopedJavaLocalRef<jobject>
+  FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jstring>& j_email) const;
 #endif
 
  private:
diff --git a/components/signin/public/identity_manager/primary_account_mutator.cc b/components/signin/public/identity_manager/primary_account_mutator.cc
new file mode 100644
index 0000000..02b4b1e
--- /dev/null
+++ b/components/signin/public/identity_manager/primary_account_mutator.cc
@@ -0,0 +1,50 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/signin/public/identity_manager/primary_account_mutator.h"
+
+#include "components/signin/public/identity_manager/account_info.h"
+
+#if defined(OS_ANDROID)
+#include "base/android/jni_string.h"
+#include "components/signin/internal/identity_manager/android/jni_headers/PrimaryAccountMutator_jni.h"
+#endif
+
+namespace signin {
+
+PrimaryAccountMutator::PrimaryAccountMutator() {
+#if defined(OS_ANDROID)
+  java_primary_account_mutator_ = Java_PrimaryAccountMutator_Constructor(
+      base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this));
+#endif
+}
+
+PrimaryAccountMutator::~PrimaryAccountMutator() {}
+
+#if defined(OS_ANDROID)
+bool PrimaryAccountMutator::SetPrimaryAccount(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& account_id) {
+  return SetPrimaryAccount(ConvertFromJavaCoreAccountId(env, account_id));
+}
+
+bool PrimaryAccountMutator::ClearPrimaryAccount(JNIEnv* env,
+                                                jint action,
+                                                jint source_metric,
+                                                jint delete_metric) {
+  return ClearPrimaryAccount(
+      ClearAccountsAction::kDefault,
+      static_cast<signin_metrics::ProfileSignout>(source_metric),
+      static_cast<signin_metrics::SignoutDelete>(delete_metric));
+}
+
+base::android::ScopedJavaLocalRef<jobject>
+PrimaryAccountMutator::GetJavaObject() {
+  DCHECK(java_primary_account_mutator_);
+  return base::android::ScopedJavaLocalRef<jobject>(
+      java_primary_account_mutator_);
+}
+#endif
+
+}  // namespace signin
diff --git a/components/signin/public/identity_manager/primary_account_mutator.h b/components/signin/public/identity_manager/primary_account_mutator.h
index 452335d11..bd6d6a4 100644
--- a/components/signin/public/identity_manager/primary_account_mutator.h
+++ b/components/signin/public/identity_manager/primary_account_mutator.h
@@ -7,6 +7,11 @@
 
 #include <string>
 
+#include "build/build_config.h"
+#if defined(OS_ANDROID)
+#include "base/android/jni_android.h"
+#endif
+
 namespace signin_metrics {
 enum ProfileSignout : int;
 enum class SignoutDelete;
@@ -19,7 +24,7 @@
 // PrimaryAccountMutator is the interface to set and clear the primary account
 // (see IdentityManager for more information).
 //
-// It is a pure interface that has concrete implementation on platform that
+// This interface has concrete implementations on platform that
 // support changing the signed-in state during the lifetime of the application.
 // On other platforms, there is no implementation, and no instance will be
 // available at runtime (thus accessors may return null).
@@ -27,14 +32,15 @@
  public:
   // Represents the options for handling the accounts known to the
   // IdentityManager upon calling ClearPrimaryAccount().
+  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin.identitymanager
   enum class ClearAccountsAction {
     kDefault,    // Default action based on internal policy.
     kKeepAll,    // Keep all accounts.
     kRemoveAll,  // Remove all accounts.
   };
 
-  PrimaryAccountMutator() = default;
-  virtual ~PrimaryAccountMutator() = default;
+  PrimaryAccountMutator();
+  virtual ~PrimaryAccountMutator();
 
   // PrimaryAccountMutator is non-copyable, non-moveable.
   PrimaryAccountMutator(PrimaryAccountMutator&& other) = delete;
@@ -79,6 +85,22 @@
       signin_metrics::ProfileSignout source_metric,
       signin_metrics::SignoutDelete delete_metric) = 0;
 #endif
+
+#if defined(OS_ANDROID)
+  // Overloads for calls from java:
+  bool SetPrimaryAccount(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& account_id);
+
+  bool ClearPrimaryAccount(JNIEnv* env,
+                           jint action,
+                           jint source_metric,
+                           jint delete_metric);
+
+  base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
+
+  base::android::ScopedJavaGlobalRef<jobject> java_primary_account_mutator_;
+#endif
 };
 
 }  // namespace signin
diff --git a/components/sync/driver/about_sync_util.cc b/components/sync/driver/about_sync_util.cc
index 795c7e7..4114273 100644
--- a/components/sync/driver/about_sync_util.cc
+++ b/components/sync/driver/about_sync_util.cc
@@ -142,7 +142,7 @@
     result.SetKey("title", base::Value(title_));
     base::Value stats(base::Value::Type::LIST);
     for (const std::unique_ptr<StatBase>& stat : stats_)
-      stats.GetList().push_back(stat->ToValue());
+      stats.Append(stat->ToValue());
     result.SetKey("data", std::move(stats));
     result.SetKey("is_sensitive", base::Value(is_sensitive_));
     return result;
@@ -174,7 +174,7 @@
   base::Value ToValue() const {
     base::Value result(base::Value::Type::LIST);
     for (const std::unique_ptr<Section>& section : sections_)
-      result.GetList().push_back(section->ToValue());
+      result.Append(section->ToValue());
     return result;
   }
 
@@ -607,10 +607,10 @@
     description.Set(full_status.sync_protocol_error.error_description);
   }
 
-  actionable_error.GetList().push_back(error_type.ToValue());
-  actionable_error.GetList().push_back(action.ToValue());
-  actionable_error.GetList().push_back(url.ToValue());
-  actionable_error.GetList().push_back(description.ToValue());
+  actionable_error.Append(error_type.ToValue());
+  actionable_error.Append(action.ToValue());
+  actionable_error.Append(url.ToValue());
+  actionable_error.Append(description.ToValue());
   about_info->SetKey("actionable_error", std::move(actionable_error));
 
   about_info->SetKey("unrecoverable_error_detected",
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc
index 4989bc9..dafc3840 100644
--- a/components/sync/driver/profile_sync_service.cc
+++ b/components/sync/driver/profile_sync_service.cc
@@ -1603,7 +1603,7 @@
   type_dict.SetKey("type", base::Value(ModelTypeToString(type)));
   type_dict.SetKey("nodes",
                    base::Value::FromUniquePtrValue(std::move(node_list)));
-  result_accumulator_->GetList().push_back(std::move(type_dict));
+  result_accumulator_->Append(std::move(type_dict));
 
   // Remember that this part of the request is satisfied.
   awaiting_types_.Remove(type);
diff --git a/components/ui_devtools/devtools_server_unittest.cc b/components/ui_devtools/devtools_server_unittest.cc
index 83020ce..3a17a96 100644
--- a/components/ui_devtools/devtools_server_unittest.cc
+++ b/components/ui_devtools/devtools_server_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/test/task_environment.h"
 #include "build/build_config.h"
 #include "components/ui_devtools/switches.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/address_list.h"
 #include "net/base/completion_once_callback.h"
 #include "net/base/test_completion_callback.h"
@@ -41,13 +42,13 @@
   auto network_service =
       network::NetworkService::Create(std::move(network_service_request),
                                       /*netlog=*/nullptr);
-  network::mojom::NetworkContextPtr network_context_ptr;
+  mojo::Remote<network::mojom::NetworkContext> network_context_remote;
   network_service_ptr->CreateNetworkContext(
-      mojo::MakeRequest(&network_context_ptr),
+      network_context_remote.BindNewPipeAndPassReceiver(),
       network::mojom::NetworkContextParams::New());
 
   std::unique_ptr<UiDevToolsServer> server =
-      UiDevToolsServer::CreateForViews(network_context_ptr.get(), fake_port);
+      UiDevToolsServer::CreateForViews(network_context_remote.get(), fake_port);
   // Connect to the server socket.
   net::AddressList addr(
       net::IPEndPoint(net::IPAddress(127, 0, 0, 1), fake_port));
diff --git a/components/webrtc_logging/browser/BUILD.gn b/components/webrtc_logging/browser/BUILD.gn
index 00736de..1121490 100644
--- a/components/webrtc_logging/browser/BUILD.gn
+++ b/components/webrtc_logging/browser/BUILD.gn
@@ -25,6 +25,7 @@
   deps = [
     ":browser",
     "//base",
+    "//base/test:test_support",
     "//content/test:test_support",
     "//testing/gtest",
   ]
diff --git a/components/webrtc_logging/browser/log_cleanup.cc b/components/webrtc_logging/browser/log_cleanup.cc
index 827f3e53..2bcdcfa 100644
--- a/components/webrtc_logging/browser/log_cleanup.cc
+++ b/components/webrtc_logging/browser/log_cleanup.cc
@@ -12,34 +12,144 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
+#include "base/optional.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/threading/scoped_blocking_call.h"
-#include "base/time/time.h"
 #include "components/webrtc_logging/browser/text_log_list.h"
 
 namespace webrtc_logging {
 
+const base::TimeDelta kTimeToKeepLogs = base::TimeDelta::FromDays(5);
+
 namespace {
 
-const int kDaysToKeepLogs = 5;
+// Tokenize a line from the log index. Return true/false to indicate if
+// the line was valid/invalid. If valid, |capture_time| and |upload_time| will
+// be populated with the relevant values. Note that |upload_time| is optional.
+bool ReadLineFromIndex(const std::string& line,
+                       base::Time* capture_time,
+                       base::Optional<base::Time>* upload_time) {
+  DCHECK(capture_time);
+  DCHECK(upload_time);
 
-// Remove any empty entries from the log list. One line is one log entry, see
-// WebRtcLogUploader::AddLocallyStoredLogInfoToUploadListFile for more
-// information about the format.
-void RemoveEmptyEntriesFromLogList(std::string* log_list) {
-  // TODO(crbug.com/826253): Make this more robust to errors; corrupt entries
-  // should also be removed. (Better to move away from a .csv altogether.)
-  static const char kEmptyLineStart[] = ",,,";  // And a timestamp after it.
-  size_t pos = 0;
-  do {
-    pos = log_list->find(kEmptyLineStart, pos);
-    if (pos == std::string::npos)
+  // Parse |upload_time|. (May be empty.)
+  size_t token_start = 0;
+  size_t token_end = line.find(",");
+  if (token_end == std::string::npos) {
+    return false;
+  }
+  const bool has_upload_time = (token_end > token_start);
+  double upload_time_double;
+  if (has_upload_time &&
+      !base::StringToDouble(line.substr(token_start, token_end - token_start),
+                            &upload_time_double)) {
+    return false;
+  }
+
+  // Skip |report_id|. (May be empty.)
+  token_start = token_end + 1;  // Start beyond the previous token.
+  if (token_start >= line.length()) {
+    return false;
+  }
+  token_end = line.find(",", token_start);
+  if (token_end == std::string::npos) {
+    return false;
+  }
+  // TODO(crbug.com/826253): Validate report ID (length and characters).
+
+  // Skip |local_id|. (May be empty.)
+  token_start = token_end + 1;  // Start beyond the previous token.
+  if (token_start >= line.length()) {
+    return false;
+  }
+  token_end = line.find(",", token_start);
+  if (token_end == std::string::npos) {
+    return false;
+  }
+  // TODO(crbug.com/826253): Validate local ID (length and characters).
+
+  // Parse |capture_time|. (May NOT be empty.)
+  token_start = token_end + 1;  // Start beyond the previous token.
+  if (token_start >= line.length()) {
+    return false;
+  }
+  token_end = line.length();
+  double capture_time_double;
+  if (token_end == std::string::npos ||
+      !base::StringToDouble(line.substr(token_start, token_end - token_start),
+                            &capture_time_double)) {
+    return false;
+  }
+
+  *capture_time = base::Time::FromDoubleT(capture_time_double);
+  *upload_time =
+      has_upload_time
+          ? base::make_optional(base::Time::FromDoubleT(upload_time_double))
+          : base::nullopt;
+
+  return true;
+}
+
+// Remove entries of obsolete logs from the log-index.
+// * If delete_begin_time.is_max(), older entries are removed and newer ones
+//   are retained. The length of time to keep logs is |kTimeToKeepLogs|.
+// * If !delete_begin_time.is_max(), logs are deleted within a time range
+//   starting at |delete_begin_time| and ending at the present moment.
+//   (In practice, we assume no logs were sent back in time from the future,
+//   so the actual range is from |delete_begin_time| and until the end of time.)
+std::string RemoveObsoleteEntriesFromLogIndex(
+    const std::string& log_index,
+    const base::Time& delete_begin_time,
+    const base::Time& now) {
+  std::string new_log_index;
+
+  // Only copy over lines which are (1) valid and (2) not obsolete.
+  for (size_t pos = 0; pos < log_index.length();) {
+    // Get |pos| to the beginning of the next non-empty line.
+    pos = log_index.find_first_not_of("\n", pos);
+    if (pos == std::string::npos) {
       break;
-    const size_t line_end = log_list->find("\n", pos);
-    DCHECK(line_end == std::string::npos || pos < line_end);
-    const size_t delete_len =
-        line_end == std::string::npos ? std::string::npos : line_end - pos + 1;
-    log_list->erase(pos, delete_len);
-  } while (pos < log_list->size());
+    }
+    DCHECK_LT(pos, log_index.length());
+
+    size_t line_end = log_index.find("\n", pos);
+    DCHECK(line_end == std::string::npos ||
+           (pos < line_end && line_end < log_index.length()));
+    if (line_end == std::string::npos) {
+      line_end = log_index.length();
+    }
+
+    const std::string line = log_index.substr(pos, line_end - pos);
+
+    base::Time capture_time;
+    base::Optional<base::Time> upload_time;
+    if (ReadLineFromIndex(line, &capture_time, &upload_time)) {
+      bool line_retained;
+      if (delete_begin_time.is_max()) {
+        // Sentinel value for deleting old files.
+        const base::Time older_timestamp =
+            upload_time.has_value() ? std::min(capture_time, *upload_time)
+                                    : capture_time;
+        base::TimeDelta file_age = now - older_timestamp;
+        line_retained = (file_age <= kTimeToKeepLogs);
+      } else {
+        const base::Time newer_timestamp =
+            upload_time.has_value() ? std::max(capture_time, *upload_time)
+                                    : capture_time;
+        line_retained = (newer_timestamp < delete_begin_time);
+      }
+
+      if (line_retained) {
+        // Only valid and not-to-be-deleted lines will be copied.
+        new_log_index += line;
+        new_log_index += "\n";
+      }
+    }
+
+    pos = line_end + 1;
+  }
+
+  return new_log_index;
 }
 
 }  // namespace
@@ -60,8 +170,6 @@
   }
 
   const base::Time now = base::Time::Now();
-  const base::TimeDelta time_to_keep_logs =
-      base::TimeDelta::FromDays(kDaysToKeepLogs);
 
   base::FilePath log_list_path =
       TextLogList::GetWebRtcLogListFileForDirectory(log_dir);
@@ -81,7 +189,6 @@
 
   // Delete relevant logs files (and their associated entries in the index).
   base::FileEnumerator log_files(log_dir, false, base::FileEnumerator::FILES);
-  bool delete_ok = true;
   for (base::FilePath name = log_files.Next(); !name.empty();
        name = log_files.Next()) {
     if (name == log_list_path)
@@ -90,11 +197,13 @@
     // TODO(crbug.com/827167): Handle mismatch between timestamps of the .gz
     // file and the .meta file, as well as with the index.
     base::TimeDelta file_age = now - file_info.GetLastModifiedTime();
-    if (file_age > time_to_keep_logs ||
+    if (file_age > kTimeToKeepLogs ||
         (!delete_begin_time.is_max() &&
          file_info.GetLastModifiedTime() > delete_begin_time)) {
-      if (!base::DeleteFile(name, false))
-        delete_ok = false;
+      if (!base::DeleteFile(name, false)) {
+        LOG(WARNING) << "Could not delete WebRTC text log file ("
+                     << file_info.GetName() << ").";
+      }
 
       // Remove the local ID from the log list file. The ID is guaranteed to be
       // unique.
@@ -106,16 +215,9 @@
     }
   }
 
-  if (!delete_ok)
-    LOG(WARNING) << "Could not delete all old WebRTC logs.";
-
-  // TODO(crbug.com/826254): Purge index file separately, too, to ensure
-  // entries for logs whose files were manually removed, are also subject
-  // to expiry and browsing data clearing.
-
-  RemoveEmptyEntriesFromLogList(&log_list);
-
   if (update_log_list) {
+    log_list =
+        RemoveObsoleteEntriesFromLogIndex(log_list, delete_begin_time, now);
     int written = base::WriteFile(log_list_path, &log_list[0], log_list.size());
     DPCHECK(written == static_cast<int>(log_list.size()));
   }
diff --git a/components/webrtc_logging/browser/log_cleanup.h b/components/webrtc_logging/browser/log_cleanup.h
index 704d9d5..907ae576 100644
--- a/components/webrtc_logging/browser/log_cleanup.h
+++ b/components/webrtc_logging/browser/log_cleanup.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_WEBRTC_LOGGING_BROWSER_LOG_CLEANUP_H_
 #define COMPONENTS_WEBRTC_LOGGING_BROWSER_LOG_CLEANUP_H_
 
+#include "base/time/time.h"
+
 namespace base {
 class FilePath;
 class Time;
@@ -12,6 +14,8 @@
 
 namespace webrtc_logging {
 
+extern const base::TimeDelta kTimeToKeepLogs;
+
 // Deletes logs files older that 5 days. Updates the log file list.
 // Must be called on a task runner that's allowed to block.
 // TODO(crbug.com/826221): Only call on the same task runner as where writing
diff --git a/components/webrtc_logging/browser/log_cleanup_unittest.cc b/components/webrtc_logging/browser/log_cleanup_unittest.cc
index 35f1f1cf..81d2a56d 100644
--- a/components/webrtc_logging/browser/log_cleanup_unittest.cc
+++ b/components/webrtc_logging/browser/log_cleanup_unittest.cc
@@ -4,27 +4,25 @@
 
 #include "components/webrtc_logging/browser/log_cleanup.h"
 
+#include "base/files/file.h"
 #include "base/files/file_enumerator.h"
-#include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
+#include "components/webrtc_logging/browser/text_log_list.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace webrtc_logging {
 
-namespace {
-
-const int kExpectedDaysToKeepLogFiles = 5;
-
-}  // namespace
-
 class WebRtcLogCleanupTest : public testing::Test {
  public:
   WebRtcLogCleanupTest() = default;
 
   void SetUp() override {
+    ASSERT_GT(kTimeToKeepLogs, base::TimeDelta::FromDays(2));
+
     // Create three files. One with modified date as of now, one with date one
     // day younger than the keep limit, one with date one day older than the
     // limit. The two former are expected to be kept and the last to be deleted
@@ -34,13 +32,11 @@
     ASSERT_TRUE(CreateTemporaryFileInDir(dir_.GetPath(), &file));
     ASSERT_TRUE(CreateTemporaryFileInDir(dir_.GetPath(), &file));
     base::Time time_expect_to_keep =
-        base::Time::Now() -
-        base::TimeDelta::FromDays(kExpectedDaysToKeepLogFiles - 1);
+        base::Time::Now() - kTimeToKeepLogs + base::TimeDelta::FromDays(1);
     TouchFile(file, time_expect_to_keep, time_expect_to_keep);
     ASSERT_TRUE(CreateTemporaryFileInDir(dir_.GetPath(), &file));
     base::Time time_expect_to_delete =
-        base::Time::Now() -
-        base::TimeDelta::FromDays(kExpectedDaysToKeepLogFiles + 1);
+        base::Time::Now() - kTimeToKeepLogs + -base::TimeDelta::FromDays(1);
     TouchFile(file, time_expect_to_delete, time_expect_to_delete);
   }
 
@@ -51,7 +47,7 @@
     for (base::FilePath name = files.Next(); !name.empty();
          name = files.Next()) {
       EXPECT_LT(base::Time::Now() - files.GetInfo().GetLastModifiedTime(),
-                base::TimeDelta::FromDays(kExpectedDaysToKeepLogFiles));
+                kTimeToKeepLogs);
       ++file_counter;
     }
     EXPECT_EQ(expected_files, file_counter);
@@ -67,12 +63,317 @@
 }
 
 TEST_F(WebRtcLogCleanupTest, DeleteOldAndRecentWebRtcLogFiles) {
-  base::Time time_begin_delete =
+  base::Time delete_begin_time =
       base::Time::Now() - base::TimeDelta::FromDays(1);
-  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), time_begin_delete);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
   VerifyFiles(1);
 }
 
-// TODO(crbug.com/826251): Write tests for the index file.
+// Fixture for testing the cleanup of entries from the index, for which the
+// log files themselves have already been deleted.
+class WebRtcTextLogIndexCleanupTest : public testing::Test {
+ public:
+  ~WebRtcTextLogIndexCleanupTest() override = default;
+
+  void SetUp() override {
+    ASSERT_TRUE(dir_.CreateUniqueTempDir());
+    log_list_path_ =
+        TextLogList::GetWebRtcLogListFileForDirectory(dir_.GetPath());
+  }
+
+  void CreateLogListFileWithContents(const std::string& contents) {
+    ASSERT_FALSE(base::PathExists(log_list_path_));  // Only call once per test.
+
+    const int len = static_cast<int>(contents.length());
+    ASSERT_EQ(base::WriteFile(log_list_path_, contents.c_str(), len), len);
+
+    ASSERT_TRUE(base::PathExists(log_list_path_));  // Only call once per test.
+  }
+
+  void ExpectContents(std::string expected_contents) {
+    ASSERT_TRUE(base::PathExists(log_list_path_));
+    std::string contents;
+    ASSERT_TRUE(ReadFileToString(log_list_path_, &contents));
+
+    // For robustness' sake, we allow non-newline-terminated lines in the file,
+    // even though we never produce them.
+    if (expected_contents.length() > 0 &&
+        expected_contents[expected_contents.length() - 1] != '\n') {
+      expected_contents += "\n";
+    }
+
+    EXPECT_EQ(contents, expected_contents);
+  }
+
+  base::ScopedTempDir dir_;
+  base::FilePath log_list_path_;
+};
+
+TEST_F(WebRtcTextLogIndexCleanupTest, OlderLinesNotDeleted) {
+  const std::string contents =
+      "100.1,report_id_1,local_id_1,101.1\n"
+      "100.2,report_id_2,local_id_2,101.2\n"
+      "100.3,report_id_3,local_id_3,101.3";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = contents;
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, LinesInDeletionTimeRangeDeleted) {
+  const std::string contents =
+      "160.1,report_id_1,local_id_1,161.1\n"
+      "100.2,report_id_2,local_id_2,101.2\n"
+      "160.3,report_id_3,local_id_3,161.3";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "100.2,report_id_2,local_id_2,101.2\n";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, ExpiredLinesDeleted) {
+  const base::Time now = base::Time::Now();
+
+  const std::string expired_capture_timestamp_line =
+      base::NumberToString((now - base::TimeDelta::FromHours(1)).ToDoubleT()) +
+      ",report_id_3,local_id_3,101.3\n";
+
+  const std::string not_expired_line =
+      base::NumberToString((now - base::TimeDelta::FromHours(2)).ToDoubleT()) +
+      ",report_id_2,local_id_2," +
+      base::NumberToString((now - base::TimeDelta::FromHours(3)).ToDoubleT()) +
+      "\n";
+
+  // Note: Would only happen if the clock is changed in between.
+  const std::string expired_upload_timestamp_line =
+      "100.1,report_id_1,local_id_1," +
+      base::NumberToString((now - base::TimeDelta::FromHours(4)).ToDoubleT()) +
+      "\n";
+
+  const std::string contents = expired_capture_timestamp_line +  //
+                               not_expired_line +                //
+                               expired_upload_timestamp_line;
+
+  CreateLogListFileWithContents(contents);
+
+  DeleteOldWebRtcLogFiles(dir_.GetPath());
+
+  const std::string expected_contents = not_expired_line;
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, AllLinesDeletedSanity) {
+  const std::string contents =
+      "160.1,report_id_1,local_id_1,161.1\n"
+      "160.2,report_id_2,local_id_2,161.2\n"
+      "160.3,report_id_3,local_id_3,161.3";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, EmptyLinesRemoved) {
+  const std::string contents =
+      "100.1,report_id_1,local_id_1,101.1\n"
+      "\n\n"
+      "100.2,report_id_2,local_id_2,101.2\n"
+      "\n"
+      "100.3,report_id_3,local_id_3,101.3\n"
+      "\n\n\n\n\n\n\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents =
+      "100.1,report_id_1,local_id_1,101.1\n"
+      "100.2,report_id_2,local_id_2,101.2\n"
+      "100.3,report_id_3,local_id_3,101.3\n";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, SanityEmptyFile) {
+  const std::string contents = "";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, SanityFileWithOneEmptyLine) {
+  const std::string contents = "\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+// SingleLineSanity and CanRemoveAllLines combined prove that we can write
+// the following tests using a single line, and not pass by mistake.
+TEST_F(WebRtcTextLogIndexCleanupTest, SingleLineSanity) {
+  const std::string contents = "100.1,report_id_1,local_id_1,101.1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = contents;
+  ExpectContents(expected_contents);
+}
+
+// SingleLineSanity and CanRemoveAllLines combined prove that we can write
+// the following tests using a single line, and not pass by mistake.
+TEST_F(WebRtcTextLogIndexCleanupTest, CanRemoveAllLines) {
+  const std::string contents = "200.1,report_id_1,local_id_1,201.1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, LinesWithoutUploadDateConsideredValid) {
+  const std::string contents = ",report_id_1,local_id_1,101.1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = contents;
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, LinesWithoutReportIdConsideredValid) {
+  const std::string contents = "100.1,,local_id_1,101.1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = contents;
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, LinesWithoutLocalIdConsideredValid) {
+  const std::string contents = "100.1,report_id_1,,101.1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = contents;
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest,
+       LinesWithoutCaptureDateConsideredInvalid) {
+  const std::string contents = "100.1,report_id_1,local_id_1,\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, CanBeConsideredObsoleteDueToCaptureDate) {
+  const std::string contents = ",report_id_1,local_id_1,161.1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, CanBeConsideredObsoleteDueToUploadDate) {
+  const std::string contents = "160.1,report_id_1,local_id_1,101.1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest, LinesWithTooFewTokensConsideredInvalid) {
+  const std::string contents = "100.1,report_id_1,local_id_1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest,
+       LinesWithTooManyTokensConsideredInvalidEmptyVersion) {
+  const std::string contents = "100.1,report_id_1,local_id_1,101.1,\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest,
+       LinesWithTooManyTokensConsideredInvalidNonEmptyVersion) {
+  const std::string contents = "100.1,report_id_1,local_id_1,101.1,102\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest,
+       LinesWithUnparsableUploadDateConsideredInvalid) {
+  const std::string contents = "100.1.2,report_id_1,local_id_1,101.1\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
+
+TEST_F(WebRtcTextLogIndexCleanupTest,
+       LinesWithUnparsableCaptureDateConsideredInvalid) {
+  const std::string contents = "100.1,report_id_1,local_id_1,101.1.2\n";
+  CreateLogListFileWithContents(contents);
+
+  const base::Time delete_begin_time = base::Time::FromDoubleT(150);
+  DeleteOldAndRecentWebRtcLogFiles(dir_.GetPath(), delete_begin_time);
+
+  const std::string expected_contents = "";
+  ExpectContents(expected_contents);
+}
 
 }  // namespace webrtc_logging
diff --git a/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc b/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
index 91318c1b..277b37e 100644
--- a/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
@@ -291,6 +291,19 @@
 
   g_object_unref(root_atk_object);
 
+  text1.SetName(text1_name + text1_name);
+  AXEventNotificationDetails event_bundle;
+  event_bundle.updates.resize(1);
+  event_bundle.updates[0].nodes.push_back(text1);
+  event_bundle.updates[0].nodes.push_back(root);
+  ASSERT_TRUE(manager->OnAccessibilityEvents(event_bundle));
+
+  // The hypertext offsets should reflect the new length of the static text.
+  verify_atk_link_text(combo_box_value.c_str(), 0, 28);
+  verify_atk_link_text(check_box_name.c_str(), 1, 44);
+  verify_atk_link_text(button_text_name.c_str(), 2, 45);
+  verify_atk_link_text(link_text_name.c_str(), 3, 46);
+
   manager.reset();
 }
 
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc
index 701378d..a532aaf 100644
--- a/content/browser/devtools/devtools_url_loader_interceptor.cc
+++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -1069,9 +1069,10 @@
 
   response_metadata_->redirect_info = std::make_unique<net::RedirectInfo>(
       net::RedirectInfo::ComputeRedirectInfo(
-          request.method, request.url, request.site_for_cookies,
-          first_party_url_policy, request.referrer_policy,
-          request.referrer.spec(), headers.response_code(), redirect_url,
+          request.method, request.url, request.request_initiator,
+          request.site_for_cookies, first_party_url_policy,
+          request.referrer_policy, request.referrer.spec(),
+          headers.response_code(), redirect_url,
           net::RedirectUtil::GetReferrerPolicyHeader(&headers),
           false /* insecure_scheme_was_upgraded */, true /* copy_fragment */));
 
diff --git a/content/browser/loader/navigation_url_loader_impl_unittest.cc b/content/browser/loader/navigation_url_loader_impl_unittest.cc
index 1e2f8738..08d8baa 100644
--- a/content/browser/loader/navigation_url_loader_impl_unittest.cc
+++ b/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -53,8 +53,7 @@
  public:
   explicit TestNavigationLoaderInterceptor(
       base::Optional<network::ResourceRequest>* most_recent_resource_request)
-      : most_recent_resource_request_(most_recent_resource_request),
-        resource_scheduler_(false) {
+      : most_recent_resource_request_(most_recent_resource_request) {
     net::URLRequestContextBuilder context_builder;
     context_builder.set_proxy_resolution_service(
         net::ProxyResolutionService::CreateDirect());
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
index 6bdbeee..83e5bdc 100644
--- a/content/browser/navigation_browsertest.cc
+++ b/content/browser/navigation_browsertest.cc
@@ -176,6 +176,40 @@
   DISALLOW_COPY_AND_ASSIGN(BrowserMessageObserver);
 };
 
+// Simulate embedders of content/ keeping track of the current visible URL using
+// NavigateStateChanged() and GetVisibleURL() API.
+class EmbedderVisibleUrlTracker : public WebContentsDelegate {
+ public:
+  const GURL& url() { return url_; }
+
+  // WebContentsDelegate's implementation:
+  void NavigationStateChanged(WebContents* source,
+                              InvalidateTypes changed_flags) override {
+    if (!(changed_flags & INVALIDATE_TYPE_URL))
+      return;
+    url_ = source->GetVisibleURL();
+    if (on_url_invalidated_)
+      std::move(on_url_invalidated_).Run();
+  }
+
+  void WaitUntilUrlInvalidated() {
+    base::RunLoop loop;
+    on_url_invalidated_ = loop.QuitClosure();
+    loop.Run();
+  }
+
+ private:
+  GURL url_;
+  base::OnceClosure on_url_invalidated_;
+};
+
+const char* non_cacheable_html_response =
+    "HTTP/1.1 200 OK\n"
+    "cache-control: no-cache, no-store, must-revalidate\n"
+    "content-type: text/html; charset=UTF-8\n"
+    "\n"
+    "HTML content.";
+
 }  // namespace
 
 // Test about navigation.
@@ -2327,4 +2361,102 @@
   ASSERT_EQ(1, controller.GetCurrentEntryIndex());
 }
 
+// Make sure embedders are notified about visible URL changes in this scenario:
+// 1. Navigate to A.
+// 2. Navigate to B.
+// 3. Add a forward entry in the history for later (same-document).
+// 4. Start navigation to C.
+// 5. Start history cross-document navigation, cancelling 4.
+// 6. Start history same-document navigation, cancelling 5.
+//
+// Regression test for https://crbug.com/998284.
+IN_PROC_BROWSER_TEST_P(NavigationBaseBrowserTest,
+                       BackForwardInOldDocumentCancelPendingNavigation) {
+  using Response = net::test_server::ControllableHttpResponse;
+  Response response_A1(embedded_test_server(), "/A");
+  Response response_A2(embedded_test_server(), "/A");
+  Response response_B1(embedded_test_server(), "/B");
+  Response response_C1(embedded_test_server(), "/C");
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  GURL url_a = embedded_test_server()->GetURL("a.com", "/A");
+  GURL url_b = embedded_test_server()->GetURL("b.com", "/B");
+  GURL url_c = embedded_test_server()->GetURL("c.com", "/C");
+
+  EmbedderVisibleUrlTracker embedder_url_tracker;
+  shell()->web_contents()->SetDelegate(&embedder_url_tracker);
+
+  // 1. Navigate to A.
+  shell()->LoadURL(url_a);
+  response_A1.WaitForRequest();
+  response_A1.Send(non_cacheable_html_response);
+  response_A1.Done();
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+  // 2. Navigate to B.
+  shell()->LoadURL(url_b);
+  response_B1.WaitForRequest();
+  response_B1.Send(non_cacheable_html_response);
+  response_B1.Done();
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+  // 3. Add a forward entry in the history for later (same-document).
+  EXPECT_TRUE(ExecJs(shell()->web_contents(), R"(
+    history.pushState({},'');
+    history.back();
+  )"));
+
+  // 4. Start navigation to C.
+  {
+    EXPECT_EQ(url_b, shell()->web_contents()->GetVisibleURL());
+    EXPECT_EQ(url_b, embedder_url_tracker.url());
+  }
+  shell()->LoadURL(url_c);
+  // TODO(arthursonzogni): The embedder_url_tracker should update to url_c at
+  // this point, but we currently rely on FrameTreeNode::DidStopLoading for
+  // invalidation and it does not occur when a prior navigation is already in
+  // progress. The browser is still waiting on the same-document
+  // "history.back()" to complete.
+  {
+    EXPECT_EQ(url_c, shell()->web_contents()->GetVisibleURL());
+    EXPECT_EQ(url_b, embedder_url_tracker.url());
+  }
+  embedder_url_tracker.WaitUntilUrlInvalidated();
+  {
+    EXPECT_EQ(url_c, shell()->web_contents()->GetVisibleURL());
+    EXPECT_EQ(url_c, embedder_url_tracker.url());
+  }
+  response_C1.WaitForRequest();
+
+  // 5. Start history cross-document navigation, cancelling 4.
+  EXPECT_TRUE(ExecJs(shell()->web_contents(), "history.back()"));
+  // TODO(arthursonzogni): The embedder_url_tracker should update the visible
+  // URL here.
+  {
+    EXPECT_EQ(url_b, shell()->web_contents()->GetVisibleURL());
+    EXPECT_EQ(url_c, embedder_url_tracker.url());
+  }
+  response_A2.WaitForRequest();
+  {
+    EXPECT_EQ(url_b, shell()->web_contents()->GetVisibleURL());
+    EXPECT_EQ(url_c, embedder_url_tracker.url());
+  }
+
+  // 6. Start history same-document navigation, cancelling 5.
+  EXPECT_TRUE(ExecJs(shell()->web_contents(), "history.forward()"));
+  {
+    EXPECT_EQ(url_b, shell()->web_contents()->GetVisibleURL());
+    EXPECT_EQ(url_c, embedder_url_tracker.url());
+  }
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+  {
+    EXPECT_EQ(url_b, shell()->web_contents()->GetVisibleURL());
+    EXPECT_EQ(url_c, embedder_url_tracker.url());
+  }
+
+  // TODO(https://crbug.com/998284): The URL tracked by the embedder should have
+  // been invalidated. At some point, |url_b| should be displayed, not |url_c|.
+}
+
 }  // namespace content
diff --git a/content/browser/network_service_browsertest.cc b/content/browser/network_service_browsertest.cc
index 41456f06..fbc15ff 100644
--- a/content/browser/network_service_browsertest.cc
+++ b/content/browser/network_service_browsertest.cc
@@ -29,6 +29,7 @@
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "content/test/content_browser_test_utils_internal.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/http_response_headers.h"
 #include "net/test/embedded_test_server/default_handlers.h"
@@ -247,12 +248,12 @@
   base::ScopedAllowBlockingForTesting allow_blocking;
 
   // Create network context with cache pointing to the temp cache dir.
-  network::mojom::NetworkContextPtr network_context;
+  mojo::Remote<network::mojom::NetworkContext> network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       network::mojom::NetworkContextParams::New();
   context_params->http_cache_path = GetCacheDirectory();
-  GetNetworkService()->CreateNetworkContext(mojo::MakeRequest(&network_context),
-                                            std::move(context_params));
+  GetNetworkService()->CreateNetworkContext(
+      network_context.BindNewPipeAndPassReceiver(), std::move(context_params));
 
   network::mojom::URLLoaderFactoryParamsPtr params =
       network::mojom::URLLoaderFactoryParams::New();
diff --git a/content/browser/network_service_instance_impl.h b/content/browser/network_service_instance_impl.h
index 6e2ea1de..9960e94 100644
--- a/content/browser/network_service_instance_impl.h
+++ b/content/browser/network_service_instance_impl.h
@@ -20,7 +20,8 @@
 
 // Registers |handler| to run (on UI thread) after NetworkServicePtr encounters
 // an error.  Note that there are no ordering guarantees wrt error handlers for
-// other interfaces (e.g. NetworkContextPtr and/or URLLoaderFactoryPtr).
+// other interfaces (e.g. mojo::Remote<NetworkContext> and/or
+// URLLoaderFactoryPtr).
 //
 // Can only be called on the UI thread.  No-op if NetworkService is disabled.
 CONTENT_EXPORT std::unique_ptr<base::CallbackList<void()>::Subscription>
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc
index f38e9df..7eb1e913 100644
--- a/content/browser/network_service_restart_browsertest.cc
+++ b/content/browser/network_service_restart_browsertest.cc
@@ -43,6 +43,8 @@
 #include "content/shell/browser/shell.h"
 #include "content/shell/browser/shell_browser_context.h"
 #include "content/test/storage_partition_test_utils.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/http_request.h"
@@ -64,12 +66,13 @@
 using SharedURLLoaderFactoryGetterCallback =
     base::OnceCallback<scoped_refptr<network::SharedURLLoaderFactory>()>;
 
-network::mojom::NetworkContextPtr CreateNetworkContext() {
-  network::mojom::NetworkContextPtr network_context;
+mojo::PendingRemote<network::mojom::NetworkContext> CreateNetworkContext() {
+  mojo::PendingRemote<network::mojom::NetworkContext> network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       network::mojom::NetworkContextParams::New();
-  GetNetworkService()->CreateNetworkContext(mojo::MakeRequest(&network_context),
-                                            std::move(context_params));
+  GetNetworkService()->CreateNetworkContext(
+      network_context.InitWithNewPipeAndPassReceiver(),
+      std::move(context_params));
   return network_context;
 }
 
@@ -315,29 +318,31 @@
                        NetworkServiceProcessRecovery) {
   if (IsInProcessNetworkService())
     return;
-  network::mojom::NetworkContextPtr network_context = CreateNetworkContext();
+  mojo::Remote<network::mojom::NetworkContext> network_context(
+      CreateNetworkContext());
   EXPECT_EQ(net::OK, LoadBasicRequest(network_context.get(), GetTestURL()));
   EXPECT_TRUE(network_context.is_bound());
-  EXPECT_FALSE(network_context.encountered_error());
+  EXPECT_TRUE(network_context.is_connected());
 
   // Crash the NetworkService process. Existing interfaces should receive error
   // notifications at some point.
   SimulateNetworkServiceCrash();
   // |network_context| will receive an error notification, but it's not
-  // guaranteed to have arrived at this point. Flush the pointer to make sure
+  // guaranteed to have arrived at this point. Flush the remote to make sure
   // the notification has been received.
   network_context.FlushForTesting();
   EXPECT_TRUE(network_context.is_bound());
-  EXPECT_TRUE(network_context.encountered_error());
+  EXPECT_FALSE(network_context.is_connected());
   // Make sure we could get |net::ERR_FAILED| with an invalid |network_context|.
   EXPECT_EQ(net::ERR_FAILED,
             LoadBasicRequest(network_context.get(), GetTestURL()));
 
   // NetworkService should restart automatically and return valid interface.
-  network::mojom::NetworkContextPtr network_context2 = CreateNetworkContext();
+  mojo::Remote<network::mojom::NetworkContext> network_context2(
+      CreateNetworkContext());
   EXPECT_EQ(net::OK, LoadBasicRequest(network_context2.get(), GetTestURL()));
   EXPECT_TRUE(network_context2.is_bound());
-  EXPECT_FALSE(network_context2.encountered_error());
+  EXPECT_TRUE(network_context2.is_connected());
 }
 
 void IncrementInt(int* i) {
@@ -349,7 +354,8 @@
 IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, CrashHandlers) {
   if (IsInProcessNetworkService())
     return;
-  network::mojom::NetworkContextPtr network_context = CreateNetworkContext();
+  mojo::Remote<network::mojom::NetworkContext> network_context(
+      CreateNetworkContext());
   EXPECT_TRUE(network_context.is_bound());
 
   // Register 2 crash handlers.
@@ -363,18 +369,19 @@
   // Crash the NetworkService process.
   SimulateNetworkServiceCrash();
   // |network_context| will receive an error notification, but it's not
-  // guaranteed to have arrived at this point. Flush the pointer to make sure
+  // guaranteed to have arrived at this point. Flush the remote to make sure
   // the notification has been received.
   network_context.FlushForTesting();
   EXPECT_TRUE(network_context.is_bound());
-  EXPECT_TRUE(network_context.encountered_error());
+  EXPECT_FALSE(network_context.is_connected());
 
   // Verify the crash handlers executed.
   EXPECT_EQ(1, counter1);
   EXPECT_EQ(1, counter2);
 
   // Revive the NetworkService process.
-  network_context = CreateNetworkContext();
+  network_context.reset();
+  network_context.Bind(CreateNetworkContext());
   EXPECT_TRUE(network_context.is_bound());
 
   // Unregister one of the handlers.
@@ -383,11 +390,11 @@
   // Crash the NetworkService process.
   SimulateNetworkServiceCrash();
   // |network_context| will receive an error notification, but it's not
-  // guaranteed to have arrived at this point. Flush the pointer to make sure
+  // guaranteed to have arrived at this point. Flush the remote to make sure
   // the notification has been received.
   network_context.FlushForTesting();
   EXPECT_TRUE(network_context.is_bound());
-  EXPECT_TRUE(network_context.encountered_error());
+  EXPECT_FALSE(network_context.is_connected());
 
   // Verify only the first crash handler executed.
   EXPECT_EQ(2, counter1);
diff --git a/content/browser/renderer_host/frame_sink_provider_impl.cc b/content/browser/renderer_host/frame_sink_provider_impl.cc
index 47ea521..919a8771 100644
--- a/content/browser/renderer_host/frame_sink_provider_impl.cc
+++ b/content/browser/renderer_host/frame_sink_provider_impl.cc
@@ -43,8 +43,8 @@
 
 void FrameSinkProviderImpl::RegisterRenderFrameMetadataObserver(
     int32_t widget_id,
-    mojom::RenderFrameMetadataObserverClientRequest
-        render_frame_metadata_observer_client_request,
+    mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+        render_frame_metadata_observer_client_receiver,
     mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
         render_frame_metadata_observer) {
   RenderWidgetHostImpl* render_widget_host_impl =
@@ -55,7 +55,7 @@
     return;
   }
   render_widget_host_impl->RegisterRenderFrameMetadataObserver(
-      std::move(render_frame_metadata_observer_client_request),
+      std::move(render_frame_metadata_observer_client_receiver),
       std::move(render_frame_metadata_observer));
 }
 
diff --git a/content/browser/renderer_host/frame_sink_provider_impl.h b/content/browser/renderer_host/frame_sink_provider_impl.h
index c90fb47..f59dee4 100644
--- a/content/browser/renderer_host/frame_sink_provider_impl.h
+++ b/content/browser/renderer_host/frame_sink_provider_impl.h
@@ -31,8 +31,8 @@
       override;
   void RegisterRenderFrameMetadataObserver(
       int32_t widget_id,
-      mojom::RenderFrameMetadataObserverClientRequest
-          render_frame_metadata_observer_client_request,
+      mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+          render_frame_metadata_observer_client_receiver,
       mojo::PendingRemote<mojom::RenderFrameMetadataObserver> observer)
       override;
 
diff --git a/content/browser/renderer_host/render_frame_metadata_provider_impl.cc b/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
index 527a9e64..498d3330 100644
--- a/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
+++ b/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
@@ -13,8 +13,7 @@
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     FrameTokenMessageQueue* frame_token_message_queue)
     : task_runner_(task_runner),
-      frame_token_message_queue_(frame_token_message_queue),
-      render_frame_metadata_observer_client_binding_(this) {}
+      frame_token_message_queue_(frame_token_message_queue) {}
 
 RenderFrameMetadataProviderImpl::~RenderFrameMetadataProviderImpl() = default;
 
@@ -27,13 +26,14 @@
 }
 
 void RenderFrameMetadataProviderImpl::Bind(
-    mojom::RenderFrameMetadataObserverClientRequest client_request,
+    mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+        client_receiver,
     mojo::PendingRemote<mojom::RenderFrameMetadataObserver> observer) {
   render_frame_metadata_observer_remote_.reset();
   render_frame_metadata_observer_remote_.Bind(std::move(observer));
-  render_frame_metadata_observer_client_binding_.Close();
-  render_frame_metadata_observer_client_binding_.Bind(std::move(client_request),
-                                                      task_runner_);
+  render_frame_metadata_observer_client_receiver_.reset();
+  render_frame_metadata_observer_client_receiver_.Bind(
+      std::move(client_receiver), task_runner_);
 
 #if defined(OS_ANDROID)
   if (pending_report_all_root_scrolls_for_accessibility_.has_value()) {
diff --git a/content/browser/renderer_host/render_frame_metadata_provider_impl.h b/content/browser/renderer_host/render_frame_metadata_provider_impl.h
index 10455e9..9c0f9c8 100644
--- a/content/browser/renderer_host/render_frame_metadata_provider_impl.h
+++ b/content/browser/renderer_host/render_frame_metadata_provider_impl.h
@@ -11,8 +11,9 @@
 #include "build/build_config.h"
 #include "content/common/render_frame_metadata.mojom.h"
 #include "content/public/browser/render_frame_metadata_provider.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
 namespace content {
@@ -38,7 +39,8 @@
   void AddObserver(Observer* observer) override;
   void RemoveObserver(Observer* observer) override;
 
-  void Bind(mojom::RenderFrameMetadataObserverClientRequest client_request,
+  void Bind(mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+                client_receiver,
             mojo::PendingRemote<mojom::RenderFrameMetadataObserver> observer);
 
   const cc::RenderFrameMetadata& LastRenderFrameMetadata() override;
@@ -86,8 +88,8 @@
   // Not owned.
   FrameTokenMessageQueue* const frame_token_message_queue_;
 
-  mojo::Binding<mojom::RenderFrameMetadataObserverClient>
-      render_frame_metadata_observer_client_binding_;
+  mojo::Receiver<mojom::RenderFrameMetadataObserverClient>
+      render_frame_metadata_observer_client_receiver_{this};
   mojo::Remote<mojom::RenderFrameMetadataObserver>
       render_frame_metadata_observer_remote_;
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 290200a..ce5c2c9 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2960,12 +2960,12 @@
 }
 
 void RenderWidgetHostImpl::RegisterRenderFrameMetadataObserver(
-    mojom::RenderFrameMetadataObserverClientRequest
-        render_frame_metadata_observer_client_request,
+    mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+        render_frame_metadata_observer_client_receiver,
     mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
         render_frame_metadata_observer) {
   render_frame_metadata_provider_.Bind(
-      std::move(render_frame_metadata_observer_client_request),
+      std::move(render_frame_metadata_observer_client_receiver),
       std::move(render_frame_metadata_observer));
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 49eaed1..5445df9 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -58,6 +58,7 @@
 #include "ipc/ipc_listener.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h"
@@ -651,8 +652,8 @@
       viz::mojom::CompositorFrameSinkClientPtr compositor_frame_sink_client);
 
   void RegisterRenderFrameMetadataObserver(
-      mojom::RenderFrameMetadataObserverClientRequest
-          render_frame_metadata_observer_client_request,
+      mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+          render_frame_metadata_observer_client_receiver,
       mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
           render_frame_metadata_observer);
 
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index d9638ea..28653b1 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -266,14 +266,15 @@
 // Fake out the renderer side of mojom::RenderFrameMetadataObserver, allowing
 // for RenderWidgetHostImpl to be created.
 //
-// All methods are no-opts, the provided mojo request and info are held, but
+// All methods are no-opts, the provided mojo receiver and remote are held, but
 // never bound.
 class FakeRenderFrameMetadataObserver
     : public mojom::RenderFrameMetadataObserver {
  public:
   FakeRenderFrameMetadataObserver(
       mojo::PendingReceiver<mojom::RenderFrameMetadataObserver> receiver,
-      mojom::RenderFrameMetadataObserverClientPtrInfo client_info);
+      mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient>
+          client_remote);
   ~FakeRenderFrameMetadataObserver() override {}
 
 #if defined(OS_ANDROID)
@@ -283,14 +284,15 @@
 
  private:
   mojo::PendingReceiver<mojom::RenderFrameMetadataObserver> receiver_;
-  mojom::RenderFrameMetadataObserverClientPtrInfo client_info_;
+  mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient> client_remote_;
   DISALLOW_COPY_AND_ASSIGN(FakeRenderFrameMetadataObserver);
 };
 
 FakeRenderFrameMetadataObserver::FakeRenderFrameMetadataObserver(
     mojo::PendingReceiver<mojom::RenderFrameMetadataObserver> receiver,
-    mojom::RenderFrameMetadataObserverClientPtrInfo client_info)
-    : receiver_(std::move(receiver)), client_info_(std::move(client_info)) {}
+    mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient> client_remote)
+    : receiver_(std::move(receiver)),
+      client_remote_(std::move(client_remote)) {}
 
 // MockRenderWidgetHostDelegate --------------------------------------------
 
@@ -509,22 +511,23 @@
 
     mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
         renderer_render_frame_metadata_observer_remote;
-    mojom::RenderFrameMetadataObserverClientPtrInfo
-        render_frame_metadata_observer_client_info;
-    mojom::RenderFrameMetadataObserverClientRequest
-        render_frame_metadata_observer_client_request =
-            mojo::MakeRequest(&render_frame_metadata_observer_client_info);
+    mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient>
+        render_frame_metadata_observer_remote;
+    mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+        render_frame_metadata_observer_client_receiver =
+            render_frame_metadata_observer_remote
+                .InitWithNewPipeAndPassReceiver();
     renderer_render_frame_metadata_observer_ =
         std::make_unique<FakeRenderFrameMetadataObserver>(
             renderer_render_frame_metadata_observer_remote
                 .InitWithNewPipeAndPassReceiver(),
-            std::move(render_frame_metadata_observer_client_info));
+            std::move(render_frame_metadata_observer_remote));
 
     host_->RequestCompositorFrameSink(
         std::move(sink_request),
         std::move(renderer_compositor_frame_sink_ptr_));
     host_->RegisterRenderFrameMetadataObserver(
-        std::move(render_frame_metadata_observer_client_request),
+        std::move(render_frame_metadata_observer_client_receiver),
         std::move(renderer_render_frame_metadata_observer_remote));
   }
 
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index c626801..7715e59 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -70,6 +70,7 @@
 #include "mojo/public/cpp/bindings/callback_helpers.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "net/base/net_errors.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/cookie_util.h"
@@ -766,10 +767,11 @@
     DCHECK((cert && private_key) || (!cert && !private_key));
 
     if (cert && private_key) {
-      network::mojom::SSLPrivateKeyPtr ssl_private_key;
+      mojo::PendingRemote<network::mojom::SSLPrivateKey> ssl_private_key;
 
-      mojo::MakeStrongBinding(std::make_unique<SSLPrivateKeyImpl>(private_key),
-                              mojo::MakeRequest(&ssl_private_key));
+      mojo::MakeSelfOwnedReceiver(
+          std::make_unique<SSLPrivateKeyImpl>(private_key),
+          ssl_private_key.InitWithNewPipeAndPassReceiver());
 
       client_cert_responder_->ContinueWithCertificate(
           cert, private_key->GetProviderName(),
@@ -2284,7 +2286,7 @@
   network_context_client_receiver_.reset();
   network_context_->SetClient(
       network_context_client_receiver_.BindNewPipeAndPassRemote());
-  network_context_.set_connection_error_handler(base::BindOnce(
+  network_context_.set_disconnect_handler(base::BindOnce(
       &StoragePartitionImpl::InitNetworkContext, weak_factory_.GetWeakPtr()));
 }
 
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 1ca85b4..8457f21 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -40,6 +40,7 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/cookie_manager.mojom.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/network_service.mojom.h"
@@ -463,7 +464,7 @@
   // service. When it's disabled, the underlying NetworkContext may either be
   // provided by the embedder, or is created by the StoragePartition and owned
   // by |network_context_owner_|.
-  network::mojom::NetworkContextPtr network_context_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_;
 
   mojo::Receiver<network::mojom::NetworkContextClient>
       network_context_client_receiver_{this};
diff --git a/content/browser/web_package/bundled_exchanges_handle.cc b/content/browser/web_package/bundled_exchanges_handle.cc
index 0dd7b0a..dd88c96 100644
--- a/content/browser/web_package/bundled_exchanges_handle.cc
+++ b/content/browser/web_package/bundled_exchanges_handle.cc
@@ -73,7 +73,8 @@
             base::StringPrintf("HTTP/1.1 %d %s\r\n", 303, "See Other")));
 
     net::RedirectInfo redirect_info = net::RedirectInfo::ComputeRedirectInfo(
-        "GET", resource_request.url, resource_request.site_for_cookies,
+        "GET", resource_request.url, resource_request.request_initiator,
+        resource_request.site_for_cookies,
         resource_request.update_first_party_url_on_redirect
             ? net::URLRequest::FirstPartyURLPolicy::
                   UPDATE_FIRST_PARTY_URL_ON_REDIRECT
diff --git a/content/browser/web_package/signed_exchange_handler_unittest.cc b/content/browser/web_package/signed_exchange_handler_unittest.cc
index 13b39bd..0133b679 100644
--- a/content/browser/web_package/signed_exchange_handler_unittest.cc
+++ b/content/browser/web_package/signed_exchange_handler_unittest.cc
@@ -22,6 +22,7 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/test/browser_task_environment.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/io_buffer.h"
 #include "net/base/load_flags.h"
 #include "net/base/test_completion_callback.h"
@@ -321,7 +322,7 @@
       std::unique_ptr<net::TestURLRequestContext> context) {
     url_request_context_ = std::move(context);
     network_context_ = std::make_unique<network::NetworkContext>(
-        nullptr, mojo::MakeRequest(&network_context_ptr_),
+        nullptr, network_context_remote_.BindNewPipeAndPassReceiver(),
         url_request_context_.get(),
         /*cors_exempt_header_list=*/std::vector<std::string>());
     SignedExchangeHandler::SetNetworkContextForTesting(network_context_.get());
@@ -406,7 +407,7 @@
   ContentBrowserClient* original_client_;
   std::unique_ptr<net::TestURLRequestContext> url_request_context_;
   std::unique_ptr<network::NetworkContext> network_context_;
-  network::mojom::NetworkContextPtr network_context_ptr_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
   const url::Origin request_initiator_;
   std::unique_ptr<SignedExchangeCertificateChain::IgnoreErrorsSPKIList>
       original_ignore_errors_spki_list_;
diff --git a/content/browser/web_package/signed_exchange_utils.cc b/content/browser/web_package/signed_exchange_utils.cc
index 153d2a7..f692760 100644
--- a/content/browser/web_package/signed_exchange_utils.cc
+++ b/content/browser/web_package/signed_exchange_utils.cc
@@ -207,7 +207,8 @@
   // https://wicg.github.io/webpackage/loading.html#mp-http-fetch
   // Step 3. Set actualResponse's status to 303. [spec text]
   return net::RedirectInfo::ComputeRedirectInfo(
-      "GET", outer_request.url, outer_request.site_for_cookies,
+      "GET", outer_request.url, outer_request.request_initiator,
+      outer_request.site_for_cookies,
       outer_request.update_first_party_url_on_redirect
           ? net::URLRequest::FirstPartyURLPolicy::
                 UPDATE_FIRST_PARTY_URL_ON_REDIRECT
diff --git a/content/browser/webrtc/webrtc_data_browsertest.cc b/content/browser/webrtc/webrtc_data_browsertest.cc
index 73fc5f9d..4ebcd5b 100644
--- a/content/browser/webrtc/webrtc_data_browsertest.cc
+++ b/content/browser/webrtc/webrtc_data_browsertest.cc
@@ -72,11 +72,17 @@
 // This test will make a PeerConnection-based call and test an unreliable text
 // dataChannel and audio and video tracks.
 // TODO(mallinath) - Remove this test after rtp based data channel is disabled.
-IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcDataBrowserTest, CallWithDataAndMedia) {
+// Flaky. crbug.com/986872
+#if defined(OS_LINUX) || defined(OS_WIN)
+#define MAYBE_CallWithDataAndMedia DISABLED_CallWithDataAndMedia
+#else
+#define MAYBE_CallWithDataAndMedia CallWithDataAndMedia
+#endif
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcDataBrowserTest,
+                       MAYBE_CallWithDataAndMedia) {
   MakeTypicalPeerConnectionCall("callWithDataAndMedia();");
 }
 
-
 #if defined(MEMORY_SANITIZER)
 // Fails under MemorySanitizer: http://crbug.com/405951
 #define MAYBE_CallWithSctpDataAndMedia DISABLED_CallWithSctpDataAndMedia
diff --git a/content/browser/webrtc/webrtc_image_capture_browsertest.cc b/content/browser/webrtc/webrtc_image_capture_browsertest.cc
index 5bb6772..a58febd 100644
--- a/content/browser/webrtc/webrtc_image_capture_browsertest.cc
+++ b/content/browser/webrtc/webrtc_image_capture_browsertest.cc
@@ -219,8 +219,14 @@
   ASSERT_TRUE(RunImageCaptureTestCase("testCreateAndGrabFrameSucceeds()"));
 }
 
+// Flaky. crbug.com/998116
+#if defined(OS_LINUX)
+#define MAYBE_GetTrackCapabilities DISABLED_GetTrackCapabilities
+#else
+#define MAYBE_GetTrackCapabilities GetTrackCapabilities
+#endif
 IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest,
-                       GetTrackCapabilities) {
+                       MAYBE_GetTrackCapabilities) {
   embedded_test_server()->StartAcceptingConnections();
   ASSERT_TRUE(RunImageCaptureTestCase("testCreateAndGetTrackCapabilities()"));
 }
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc
index 0fc6a17..ad639e3 100644
--- a/content/browser/worker_host/worker_script_fetch_initiator.cc
+++ b/content/browser/worker_host/worker_script_fetch_initiator.cc
@@ -310,7 +310,6 @@
     // network service after a crash, but it's OK since it's used only for a
     // single request to fetch the worker's main script during startup. If the
     // network service crashes, worker startup should simply fail.
-    network::mojom::URLLoaderFactoryPtr network_factory_ptr;
     auto network_factory =
         storage_partition->GetURLLoaderFactoryForBrowserProcess();
     network_factory->Clone(std::move(default_factory_receiver));
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index 5ae2848..6014dde 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -62,6 +62,7 @@
 #include "ipc/ipc_sync_channel.h"
 #include "ipc/ipc_sync_message_filter.h"
 #include "mojo/core/embedder/scoped_ipc_support.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "mojo/public/cpp/platform/named_platform_channel.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
@@ -415,13 +416,13 @@
     base::RepeatingClosure quit_closure,
     ChildThreadImpl::Options::ServiceBinder service_binder,
     mojo::PendingReceiver<mojom::ChildProcessHost> host_receiver,
-    mojom::ChildProcessRequest request) {
+    mojo::PendingReceiver<mojom::ChildProcess> receiver) {
   mojo::MakeSelfOwnedReceiver<mojom::ChildProcess>(
       std::make_unique<ChildProcessImpl>(
           std::move(main_thread_task_runner), std::move(weak_main_thread),
           std::move(quit_closure), std::move(service_binder),
           std::move(host_receiver)),
-      std::move(request));
+      std::move(receiver));
 }
 
 }  // namespace
diff --git a/content/common/frame_sink_provider.mojom b/content/common/frame_sink_provider.mojom
index f82a4f91..3b75486 100644
--- a/content/common/frame_sink_provider.mojom
+++ b/content/common/frame_sink_provider.mojom
@@ -19,8 +19,8 @@
 
    RegisterRenderFrameMetadataObserver(
       int32  widget_id,
-      RenderFrameMetadataObserverClient&
-        render_frame_metadata_observer_client_request,
+      pending_receiver<RenderFrameMetadataObserverClient>
+        render_frame_metadata_observer_client_receiver,
       pending_remote<RenderFrameMetadataObserver>
         render_frame_metadata_observer);
 };
diff --git a/content/common/service_worker/service_worker_loader_helpers.cc b/content/common/service_worker/service_worker_loader_helpers.cc
index 43fe683..95d64ce 100644
--- a/content/common/service_worker/service_worker_loader_helpers.cc
+++ b/content/common/service_worker/service_worker_loader_helpers.cc
@@ -128,8 +128,8 @@
           : net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
   return net::RedirectInfo::ComputeRedirectInfo(
       original_request.method, original_request.url,
-      original_request.site_for_cookies, first_party_url_policy,
-      original_request.referrer_policy,
+      original_request.request_initiator, original_request.site_for_cookies,
+      first_party_url_policy, original_request.referrer_policy,
       network::ComputeReferrer(original_request.referrer),
       response_head.headers->response_code(),
       original_request.url.Resolve(new_location),
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc
index 41f1ab32c..e71e8a68 100644
--- a/content/common/throttling_url_loader.cc
+++ b/content/common/throttling_url_loader.cc
@@ -392,6 +392,7 @@
 
     net::RedirectInfo redirect_info = net::RedirectInfo::ComputeRedirectInfo(
         start_info_->url_request.method, start_info_->url_request.url,
+        start_info_->url_request.request_initiator,
         start_info_->url_request.site_for_cookies, first_party_url_policy,
         start_info_->url_request.referrer_policy,
         start_info_->url_request.referrer.spec(),
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 643a36f..6d2b19d 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -778,18 +778,19 @@
 void ContentBrowserClient::OnNetworkServiceCreated(
     network::mojom::NetworkService* network_service) {}
 
-network::mojom::NetworkContextPtr ContentBrowserClient::CreateNetworkContext(
+mojo::Remote<network::mojom::NetworkContext>
+ContentBrowserClient::CreateNetworkContext(
     BrowserContext* context,
     bool in_memory,
     const base::FilePath& relative_partition_path) {
   DCHECK(context);
-  network::mojom::NetworkContextPtr network_context;
+  mojo::Remote<network::mojom::NetworkContext> network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       network::mojom::NetworkContextParams::New();
   context_params->user_agent = GetUserAgent();
   context_params->accept_language = "en-us,en";
-  GetNetworkService()->CreateNetworkContext(MakeRequest(&network_context),
-                                            std::move(context_params));
+  GetNetworkService()->CreateNetworkContext(
+      network_context.BindNewPipeAndPassReceiver(), std::move(context_params));
   return network_context;
 }
 
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 44887837..a9131e7 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -44,6 +44,7 @@
 #include "media/mojo/mojom/remoting.mojom.h"
 #include "mojo/public/cpp/bindings/generic_pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/mime_util.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "services/network/public/mojom/network_context.mojom.h"
@@ -1377,7 +1378,7 @@
   // For NetworkContexts returned from the Network Service, some requirements:
   //   -enable data URL support (or else data URLs will fail)
   //   -disable file URL support (for security)
-  virtual network::mojom::NetworkContextPtr CreateNetworkContext(
+  virtual mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       BrowserContext* context,
       bool in_memory,
       const base::FilePath& relative_partition_path);
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index 5b045bc..d771ec5 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -507,7 +507,6 @@
           EXPECT_EQ(0u, result->number_of_live_resources);
           EXPECT_EQ(0u,
                     result->number_of_live_context_lifecycle_state_observers);
-          EXPECT_EQ(0u, result->number_of_live_script_promises);
           EXPECT_EQ(0u, result->number_of_live_frames);
           EXPECT_EQ(0u, result->number_of_live_v8_per_context_data);
           EXPECT_EQ(0u, result->number_of_worker_global_scopes);
diff --git a/content/renderer/compositor/compositor_dependencies.h b/content/renderer/compositor/compositor_dependencies.h
index aa8dbbc7..9ce2b02 100644
--- a/content/renderer/compositor/compositor_dependencies.h
+++ b/content/renderer/compositor/compositor_dependencies.h
@@ -12,6 +12,7 @@
 #include "components/viz/common/display/renderer_settings.h"
 #include "content/common/content_export.h"
 #include "content/common/render_frame_metadata.mojom.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 
 class GURL;
@@ -64,8 +65,8 @@
       scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
       const GURL& url,
       LayerTreeFrameSinkCallback callback,
-      mojom::RenderFrameMetadataObserverClientRequest
-          render_frame_metadata_observer_client_request,
+      mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+          render_frame_metadata_observer_client_receiver,
       mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
           render_frame_metadata_observer_remote,
       const char* client_name) = 0;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index fde26fc..4e17b17 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -454,8 +454,9 @@
   navigation_params->ip_address_space = commit_params.ip_address_space;
 
   if (common_params.referrer->url.is_valid()) {
+    url::Origin origin = common_params.initiator_origin.value_or(url::Origin());
     WebString referrer = WebSecurityPolicy::GenerateReferrerHeader(
-        common_params.referrer->policy, common_params.url,
+        common_params.referrer->policy, origin, common_params.url,
         WebString::FromUTF8(common_params.referrer->url.spec()));
     navigation_params->referrer = referrer;
     navigation_params->referrer_policy = common_params.referrer->policy;
@@ -502,7 +503,7 @@
       WebURLLoaderImpl::PopulateURLResponse(
           exchange->inner_url,
           network::ResourceResponseHead(exchange->inner_response),
-          &web_response, false /* report_security_info*/, -1 /* request_id */);
+          &web_response, false /* report_security_info */, -1 /* request_id */);
       navigation_params->prefetched_signed_exchanges.emplace_back(
           std::make_unique<
               blink::WebNavigationParams::PrefetchedSignedExchange>(
diff --git a/content/renderer/render_frame_metadata_observer_impl.cc b/content/renderer/render_frame_metadata_observer_impl.cc
index 58df056..cf7841a 100644
--- a/content/renderer/render_frame_metadata_observer_impl.cc
+++ b/content/renderer/render_frame_metadata_observer_impl.cc
@@ -19,15 +19,16 @@
 
 RenderFrameMetadataObserverImpl::RenderFrameMetadataObserverImpl(
     mojo::PendingReceiver<mojom::RenderFrameMetadataObserver> receiver,
-    mojom::RenderFrameMetadataObserverClientPtrInfo client_info)
-    : receiver_(std::move(receiver)), client_info_(std::move(client_info)) {}
+    mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient> client_remote)
+    : receiver_(std::move(receiver)),
+      client_remote_(std::move(client_remote)) {}
 
 RenderFrameMetadataObserverImpl::~RenderFrameMetadataObserverImpl() {}
 
 void RenderFrameMetadataObserverImpl::BindToCurrentThread() {
   DCHECK(receiver_.is_valid());
   render_frame_metadata_observer_receiver_.Bind(std::move(receiver_));
-  render_frame_metadata_observer_client_.Bind(std::move(client_info_));
+  render_frame_metadata_observer_client_.Bind(std::move(client_remote_));
 }
 
 void RenderFrameMetadataObserverImpl::OnRenderFrameSubmission(
diff --git a/content/renderer/render_frame_metadata_observer_impl.h b/content/renderer/render_frame_metadata_observer_impl.h
index 53b565f..f253f7b82 100644
--- a/content/renderer/render_frame_metadata_observer_impl.h
+++ b/content/renderer/render_frame_metadata_observer_impl.h
@@ -11,7 +11,9 @@
 #include "content/common/content_export.h"
 #include "content/common/render_frame_metadata.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
 
 namespace content {
 
@@ -30,7 +32,8 @@
  public:
   RenderFrameMetadataObserverImpl(
       mojo::PendingReceiver<mojom::RenderFrameMetadataObserver> receiver,
-      mojom::RenderFrameMetadataObserverClientPtrInfo client_info);
+      mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient>
+          client_remote);
   ~RenderFrameMetadataObserverImpl() override;
 
   // cc::RenderFrameMetadataObserver:
@@ -76,11 +79,11 @@
 
   // These are destroyed when BindToCurrentThread() is called.
   mojo::PendingReceiver<mojom::RenderFrameMetadataObserver> receiver_;
-  mojom::RenderFrameMetadataObserverClientPtrInfo client_info_;
+  mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient> client_remote_;
 
   mojo::Receiver<mojom::RenderFrameMetadataObserver>
       render_frame_metadata_observer_receiver_{this};
-  mojom::RenderFrameMetadataObserverClientPtr
+  mojo::Remote<mojom::RenderFrameMetadataObserverClient>
       render_frame_metadata_observer_client_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderFrameMetadataObserverImpl);
diff --git a/content/renderer/render_frame_metadata_observer_impl_unittest.cc b/content/renderer/render_frame_metadata_observer_impl_unittest.cc
index 3663d7a1..0883bde 100644
--- a/content/renderer/render_frame_metadata_observer_impl_unittest.cc
+++ b/content/renderer/render_frame_metadata_observer_impl_unittest.cc
@@ -11,6 +11,7 @@
 #include "components/viz/common/quads/compositor_frame_metadata.h"
 #include "content/common/render_frame_metadata.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -29,11 +30,12 @@
     : public mojom::RenderFrameMetadataObserverClient {
  public:
   MockRenderFrameMetadataObserverClient(
-      mojom::RenderFrameMetadataObserverClientRequest client_request,
+      mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+          client_receiver,
       mojo::PendingRemote<mojom::RenderFrameMetadataObserver> observer)
       : render_frame_metadata_observer_client_binding_(
             this,
-            std::move(client_request)),
+            std::move(client_receiver)),
         render_frame_metadata_observer_remote_(std::move(observer)) {}
 
   MOCK_METHOD2(OnRenderFrameMetadataChanged,
@@ -64,15 +66,14 @@
     mojo::PendingRemote<mojom::RenderFrameMetadataObserver> observer_remote;
     mojo::PendingReceiver<mojom::RenderFrameMetadataObserver> receiver =
         observer_remote.InitWithNewPipeAndPassReceiver();
-    mojom::RenderFrameMetadataObserverClientPtrInfo client_info;
-    mojom::RenderFrameMetadataObserverClientRequest client_request =
-        mojo::MakeRequest(&client_info);
+    mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient> client_remote;
 
     client_ = std::make_unique<
         testing::NiceMock<MockRenderFrameMetadataObserverClient>>(
-        std::move(client_request), std::move(observer_remote));
+        client_remote.InitWithNewPipeAndPassReceiver(),
+        std::move(observer_remote));
     observer_impl_ = std::make_unique<RenderFrameMetadataObserverImpl>(
-        std::move(receiver), std::move(client_info));
+        std::move(receiver), std::move(client_remote));
     observer_impl_->BindToCurrentThread();
   }
 
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index e5fdbd3..49f3e19 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1847,8 +1847,8 @@
     scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
     const GURL& url,
     LayerTreeFrameSinkCallback callback,
-    mojom::RenderFrameMetadataObserverClientRequest
-        render_frame_metadata_observer_client_request,
+    mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+        render_frame_metadata_observer_client_receiver,
     mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
         render_frame_metadata_observer_remote,
     const char* client_name) {
@@ -1902,7 +1902,7 @@
         std::move(compositor_frame_sink_client));
     frame_sink_provider_->RegisterRenderFrameMetadataObserver(
         widget_routing_id,
-        std::move(render_frame_metadata_observer_client_request),
+        std::move(render_frame_metadata_observer_client_receiver),
         std::move(render_frame_metadata_observer_remote));
     std::move(callback).Run(
         std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
@@ -1965,7 +1965,7 @@
       // TODO(ericrk): Collapse with non-webview registration below.
       frame_sink_provider_->RegisterRenderFrameMetadataObserver(
           widget_routing_id,
-          std::move(render_frame_metadata_observer_client_request),
+          std::move(render_frame_metadata_observer_client_receiver),
           std::move(render_frame_metadata_observer_remote));
 
       std::move(callback).Run(std::make_unique<SynchronousLayerTreeFrameSink>(
@@ -1988,7 +1988,7 @@
       std::move(compositor_frame_sink_client));
   frame_sink_provider_->RegisterRenderFrameMetadataObserver(
       widget_routing_id,
-      std::move(render_frame_metadata_observer_client_request),
+      std::move(render_frame_metadata_observer_client_receiver),
       std::move(render_frame_metadata_observer_remote));
   params.gpu_memory_buffer_manager = GetGpuMemoryBufferManager();
   std::move(callback).Run(
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index 54e3c5a..b1bc912 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -47,6 +47,7 @@
 #include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
@@ -238,8 +239,8 @@
       scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
       const GURL& url,
       LayerTreeFrameSinkCallback callback,
-      mojom::RenderFrameMetadataObserverClientRequest
-          render_frame_metadata_observer_client_request,
+      mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+          render_frame_metadata_observer_client_receiver,
       mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
           render_frame_metadata_observer_remote,
       const char* client_name) override;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 8e6a8c9..074a065 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1177,13 +1177,13 @@
   // TODO(jonross): have this generated by the LayerTreeFrameSink itself, which
   // would then handle binding.
   mojo::PendingRemote<mojom::RenderFrameMetadataObserver> observer_remote;
-  mojom::RenderFrameMetadataObserverClientPtrInfo client_info;
-  mojom::RenderFrameMetadataObserverClientRequest client_request =
-      mojo::MakeRequest(&client_info);
+  mojo::PendingRemote<mojom::RenderFrameMetadataObserverClient> client_remote;
+  mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+      client_receiver = client_remote.InitWithNewPipeAndPassReceiver();
   auto render_frame_metadata_observer =
       std::make_unique<RenderFrameMetadataObserverImpl>(
           observer_remote.InitWithNewPipeAndPassReceiver(),
-          std::move(client_info));
+          std::move(client_remote));
   layer_tree_view_->SetRenderFrameObserver(
       std::move(render_frame_metadata_observer));
   GURL url = GetWebWidget()->GetURLForDebugTrace();
@@ -1199,7 +1199,7 @@
   const char* client_name = for_child_local_root_frame_ ? kOOPIF : kRenderer;
   compositor_deps_->RequestNewLayerTreeFrameSink(
       routing_id_, frame_swap_message_queue_, std::move(url),
-      std::move(callback), std::move(client_request),
+      std::move(callback), std::move(client_receiver),
       std::move(observer_remote), client_name);
 }
 
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 924618d..5bcdd70 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -497,12 +497,12 @@
 }
 #endif  // OS_WIN
 
-network::mojom::NetworkContextPtr
+mojo::Remote<network::mojom::NetworkContext>
 ShellContentBrowserClient::CreateNetworkContext(
     BrowserContext* context,
     bool in_memory,
     const base::FilePath& relative_partition_path) {
-  network::mojom::NetworkContextPtr network_context;
+  mojo::Remote<network::mojom::NetworkContext> network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       network::mojom::NetworkContextParams::New();
   UpdateCorsExemptHeader(context_params.get());
@@ -523,8 +523,8 @@
   }
 #endif
 
-  GetNetworkService()->CreateNetworkContext(MakeRequest(&network_context),
-                                            std::move(context_params));
+  GetNetworkService()->CreateNetworkContext(
+      network_context.BindNewPipeAndPassReceiver(), std::move(context_params));
   return network_context;
 }
 
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h
index 983b238..4d8d903 100644
--- a/content/shell/browser/shell_content_browser_client.h
+++ b/content/shell/browser/shell_content_browser_client.h
@@ -101,7 +101,7 @@
                         RendererSpawnFlags flags) override;
 #endif
 
-  network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(
       BrowserContext* context,
       bool in_memory,
       const base::FilePath& relative_partition_path) override;
diff --git a/content/shell/browser/web_test/leak_detector.cc b/content/shell/browser/web_test/leak_detector.cc
index 085f931..d13429e3 100644
--- a/content/shell/browser/web_test/leak_detector.cc
+++ b/content/shell/browser/web_test/leak_detector.cc
@@ -28,7 +28,6 @@
 const int kInitialNumberOfLiveNodes = 4;
 const int kInitialNumberOfLiveLayoutObjects = 3;
 const int kInitialNumberOfLiveResources = 0;
-const int kInitialNumberOfScriptPromises = 0;
 const int kInitialNumberOfLiveFrames = 1;
 const int kInitialNumberOfWorkerGlobalScopes = 0;
 const int kInitialNumberOfLiveResourceFetchers = 1;
@@ -50,8 +49,6 @@
   previous_result_->number_of_live_resources = kInitialNumberOfLiveResources;
   previous_result_->number_of_live_context_lifecycle_state_observers =
       kInitialNumberOfLiveContextLifecycleStateObservers;
-  previous_result_->number_of_live_script_promises =
-      kInitialNumberOfScriptPromises;
   previous_result_->number_of_live_frames = kInitialNumberOfLiveFrames;
   previous_result_->number_of_live_v8_per_context_data =
       kInitialNumberOfV8PerContextData;
@@ -127,13 +124,6 @@
           result->number_of_live_context_lifecycle_state_observers);
       detail.Set("numberOfLiveContextLifecycleStateObservers", std::move(list));
     }
-    if (previous_result_->number_of_live_script_promises <
-        result->number_of_live_script_promises) {
-      auto list = std::make_unique<base::ListValue>();
-      list->AppendInteger(previous_result_->number_of_live_script_promises);
-      list->AppendInteger(result->number_of_live_script_promises);
-      detail.Set("numberOfLiveScriptPromises", std::move(list));
-    }
     if (previous_result_->number_of_live_frames <
         result->number_of_live_frames) {
       auto list = std::make_unique<base::ListValue>();
diff --git a/content/test/fake_compositor_dependencies.cc b/content/test/fake_compositor_dependencies.cc
index 9791847..0d26bd0 100644
--- a/content/test/fake_compositor_dependencies.cc
+++ b/content/test/fake_compositor_dependencies.cc
@@ -87,8 +87,8 @@
     scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
     const GURL& url,
     LayerTreeFrameSinkCallback callback,
-    mojom::RenderFrameMetadataObserverClientRequest
-        render_frame_metadata_observer_client_request,
+    mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+        render_frame_metadata_observer_client_receiver,
     mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
         render_frame_metadata_observer_remote,
     const char* client_name) {
diff --git a/content/test/fake_compositor_dependencies.h b/content/test/fake_compositor_dependencies.h
index 2305748e..b13f5c0 100644
--- a/content/test/fake_compositor_dependencies.h
+++ b/content/test/fake_compositor_dependencies.h
@@ -9,6 +9,7 @@
 #include "base/single_thread_task_runner.h"
 #include "cc/test/test_task_graph_runner.h"
 #include "content/renderer/compositor/compositor_dependencies.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/blink/public/platform/scheduler/test/web_fake_thread_scheduler.h"
 
@@ -41,8 +42,8 @@
       scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
       const GURL& url,
       LayerTreeFrameSinkCallback callback,
-      mojom::RenderFrameMetadataObserverClientRequest
-          render_frame_metadata_observer_client_request,
+      mojo::PendingReceiver<mojom::RenderFrameMetadataObserverClient>
+          render_frame_metadata_observer_client_receiver,
       mojo::PendingRemote<mojom::RenderFrameMetadataObserver>
           render_frame_metadata_observer_remote,
       const char* client_name) override;
diff --git a/docs/security/faq.md b/docs/security/faq.md
index 58603b70..d57a52e 100644
--- a/docs/security/faq.md
+++ b/docs/security/faq.md
@@ -523,9 +523,9 @@
 responder (a third party).
 
 That said, you can use enterprise policies to [enable soft-fail
-OCSP](https://www.chromium.org/administrators/policy-list-3#EnableOnlineRevocationChecks)
+OCSP](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=EnableOnlineRevocationChecks)
 and hard-fail OCSP for [local trust
-anchors](https://www.chromium.org/administrators/policy-list-3#RequireOnlineRevocationChecksForLocalAnchors).
+anchors](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=RequireOnlineRevocationChecksForLocalAnchors).
 
 Chrome performs online checking for [Extended
 Validation](https://cabforum.org/about-ev-ssl/) certificates if it does not
diff --git a/docs/security/permissions-for-powerful-web-platform-features.md b/docs/security/permissions-for-powerful-web-platform-features.md
index cb42175..f2a25114 100644
--- a/docs/security/permissions-for-powerful-web-platform-features.md
+++ b/docs/security/permissions-for-powerful-web-platform-features.md
@@ -1,7 +1,7 @@
 # Controlling Access to Powerful Web Platform Features
 
-_Author: [dominickn@chromium.org](mailto:dominickn@chromium.org)_  
-_Contributors: [rorymcclelland@chromium.org](mailto:rorymcclelland@chromium.org)_  
+_Author: [dominickn@chromium.org](mailto:dominickn@chromium.org)_
+_Contributors: [rorymcclelland@chromium.org](mailto:rorymcclelland@chromium.org)_
 
 # Overview
 
@@ -216,7 +216,7 @@
 ### Administrator policies may override prompts and enforce persistence
 
 Powerful new capabilities may be paired with
-[Chromium policies](https://www.chromium.org/administrators/policy-list-3)
+[Chromium policies](https://cloud.google.com/docs/chrome-enterprise/policies)
 which permit administrators to enforce persisted access to capabilities
 without prompts. Capabilities may also be restricted or blocked by such
 policies. This is in line with how many existing permissions have admin policy
diff --git a/docs/security/rule-of-2.md b/docs/security/rule-of-2.md
index 8e91db00..95c54c0 100644
--- a/docs/security/rule-of-2.md
+++ b/docs/security/rule-of-2.md
@@ -101,7 +101,7 @@
 processes with [Site
 Isolation](https://www.chromium.org/Home/chromium-security/site-isolation) (very
 good) or [origin
-isolation](https://www.chromium.org/administrators/policy-list-3#IsolateOrigins)
+isolation](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=IsolateOrigins)
 (even better).
 
 ## Solutions To This Puzzle
diff --git a/docs/security/side-channel-threat-model.md b/docs/security/side-channel-threat-model.md
index 09f5eff..05f34b0 100644
--- a/docs/security/side-channel-threat-model.md
+++ b/docs/security/side-channel-threat-model.md
@@ -209,9 +209,9 @@
 
 Click To Play greatly reduces the risk that Flash-borne Spectre (and other)
 exploits will be effective at scale.  Additionally, the enterprise policies
-[PluginsBlockedForUrls](https://www.chromium.org/administrators/policy-list-3#PluginsBlockedForUrls)
+[PluginsBlockedForUrls](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=PluginsBlockedForUrls)
 and
-[PluginsAllowedForUrls](https://www.chromium.org/administrators/policy-list-3#PluginsAllowedForUrls)
+[PluginsAllowedForUrls](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=PluginsAllowedForUrls)
 can be combined to restrict Flash to specific websites.
 Even so,
 [we might want to consider teaching CORB about Flash flavour of CORS](https://crbug.com/816318).
diff --git a/docs/webview_policies.md b/docs/webview_policies.md
index 51f9619..c695f1d2 100644
--- a/docs/webview_policies.md
+++ b/docs/webview_policies.md
@@ -19,4 +19,4 @@
 
 [3]: https://developer.android.com/training/enterprise/work-policy-ctrl.html#apply_restrictions
 [1]: https://developer.android.com/training/enterprise/app-restrictions.html
-[2]: https://www.chromium.org/administrators/policy-list-3
+[2]: https://cloud.google.com/docs/chrome-enterprise/policies
diff --git a/extensions/browser/api/web_request/web_request_api_helpers.cc b/extensions/browser/api/web_request/web_request_api_helpers.cc
index 1208302..e528064 100644
--- a/extensions/browser/api/web_request/web_request_api_helpers.cc
+++ b/extensions/browser/api/web_request/web_request_api_helpers.cc
@@ -37,6 +37,7 @@
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extensions_browser_client.h"
 #include "extensions/browser/runtime_data.h"
+#include "extensions/common/extension_features.h"
 #include "extensions/common/extension_messages.h"
 #include "net/cookies/cookie_util.h"
 #include "net/cookies/parsed_cookie.h"
@@ -334,7 +335,10 @@
 
 bool ExtraInfoSpec::InitFromValue(const base::ListValue& value,
                                   int* extra_info_spec) {
-  *extra_info_spec = 0;
+  *extra_info_spec = base::FeatureList::IsEnabled(
+                         extensions_features::kForceWebRequestExtraHeaders)
+                         ? EXTRA_HEADERS
+                         : 0;
   for (size_t i = 0; i < value.GetSize(); ++i) {
     std::string str;
     if (!value.GetString(i, &str))
diff --git a/extensions/browser/json_file_sanitizer.cc b/extensions/browser/json_file_sanitizer.cc
index 31535ee..97ff819 100644
--- a/extensions/browser/json_file_sanitizer.cc
+++ b/extensions/browser/json_file_sanitizer.cc
@@ -64,7 +64,7 @@
     return;
   }
 
-  connector->BindInterface(service_filter, &json_parser_ptr_);
+  connector->Connect(service_filter, json_parser_.BindNewPipeAndPassReceiver());
 
   for (const base::FilePath& path : file_paths_) {
     base::PostTaskAndReplyWithResult(
@@ -86,10 +86,9 @@
     ReportError(Status::kFileDeleteError, std::string());
     return;
   }
-  json_parser_ptr_->Parse(
-      std::get<0>(read_and_delete_result),
-      base::BindOnce(&JsonFileSanitizer::JsonParsingDone,
-                     weak_factory_.GetWeakPtr(), file_path));
+  json_parser_->Parse(std::get<0>(read_and_delete_result),
+                      base::BindOnce(&JsonFileSanitizer::JsonParsingDone,
+                                     weak_factory_.GetWeakPtr(), file_path));
 }
 
 void JsonFileSanitizer::JsonParsingDone(
diff --git a/extensions/browser/json_file_sanitizer.h b/extensions/browser/json_file_sanitizer.h
index 070e75e..1df4c330 100644
--- a/extensions/browser/json_file_sanitizer.h
+++ b/extensions/browser/json_file_sanitizer.h
@@ -15,6 +15,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "base/values.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/data_decoder/public/mojom/json_parser.mojom.h"
 #include "services/service_manager/public/cpp/service_filter.h"
 
@@ -90,7 +91,7 @@
 
   std::set<base::FilePath> file_paths_;
   Callback callback_;
-  data_decoder::mojom::JsonParserPtr json_parser_ptr_;
+  mojo::Remote<data_decoder::mojom::JsonParser> json_parser_;
   base::WeakPtrFactory<JsonFileSanitizer> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(JsonFileSanitizer);
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc
index 17f70a1..d551544 100644
--- a/extensions/browser/sandboxed_unpacker.cc
+++ b/extensions/browser/sandboxed_unpacker.cc
@@ -731,9 +731,10 @@
 
 data_decoder::mojom::JsonParser* SandboxedUnpacker::GetJsonParserPtr() {
   DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
-  if (!json_parser_ptr_) {
-    connector_->BindInterface(data_decoder_service_filter_, &json_parser_ptr_);
-    json_parser_ptr_.set_connection_error_handler(base::BindOnce(
+  if (!json_parser_) {
+    connector_->Connect(data_decoder_service_filter_,
+                        json_parser_.BindNewPipeAndPassReceiver());
+    json_parser_.set_disconnect_handler(base::BindOnce(
         &SandboxedUnpacker::ReportFailure, this,
         SandboxedUnpackerFailureReason::
             UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
@@ -743,7 +744,7 @@
             ASCIIToUTF16(". ") +
             l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)));
   }
-  return json_parser_ptr_.get();
+  return json_parser_.get();
 }
 
 void SandboxedUnpacker::ReportUnpackExtensionFailed(base::StringPiece error) {
@@ -1003,7 +1004,7 @@
   connector_.reset();
   image_sanitizer_.reset();
   json_file_sanitizer_.reset();
-  json_parser_ptr_.reset();
+  json_parser_.reset();
 }
 
 void SandboxedUnpacker::ParseJsonFile(
diff --git a/extensions/browser/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h
index c3d1dbb..79286a6 100644
--- a/extensions/browser/sandboxed_unpacker.h
+++ b/extensions/browser/sandboxed_unpacker.h
@@ -22,6 +22,7 @@
 #include "extensions/browser/install/crx_install_error.h"
 #include "extensions/browser/json_file_sanitizer.h"
 #include "extensions/common/manifest.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/data_decoder/public/mojom/json_parser.mojom.h"
 #include "services/service_manager/public/cpp/service_filter.h"
 
@@ -294,8 +295,8 @@
   // data decoder operation use that process.
   const service_manager::ServiceFilter data_decoder_service_filter_;
 
-  // The JSONParser interface pointer from the data decoder service.
-  data_decoder::mojom::JsonParserPtr json_parser_ptr_;
+  // The JSONParser remote from the data decoder service.
+  mojo::Remote<data_decoder::mojom::JsonParser> json_parser_;
 
   // The ImageSanitizer used to clean-up images.
   std::unique_ptr<ImageSanitizer> image_sanitizer_;
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc
index 3370c10..b0d53c7 100644
--- a/extensions/common/extension_features.cc
+++ b/extensions/common/extension_features.cc
@@ -6,6 +6,12 @@
 
 namespace extensions_features {
 
+// Forces to handle event listeners as it specifies the "extraHeaders" option.
+// TODO(crbug.com/1000982, 1000984): Run a field trial, and convert to a
+// short-term enterprise policy.
+const base::Feature kForceWebRequestExtraHeaders{
+    "ForceWebRequestExtraHeaders", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Forces requests to go through WebRequestProxyingURLLoaderFactory.
 const base::Feature kForceWebRequestProxyForTest{
     "ForceWebRequestProxyForTest", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/extensions/common/extension_features.h b/extensions/common/extension_features.h
index fab080e..d77c99f 100644
--- a/extensions/common/extension_features.h
+++ b/extensions/common/extension_features.h
@@ -9,6 +9,7 @@
 
 namespace extensions_features {
 
+extern const base::Feature kForceWebRequestExtraHeaders;
 extern const base::Feature kForceWebRequestProxyForTest;
 
 }  // namespace extensions_features
diff --git a/headless/lib/browser/headless_browser_context_impl.cc b/headless/lib/browser/headless_browser_context_impl.cc
index 3f20abd..299e350 100644
--- a/headless/lib/browser/headless_browser_context_impl.cc
+++ b/headless/lib/browser/headless_browser_context_impl.cc
@@ -281,7 +281,7 @@
   return UniqueId();
 }
 
-::network::mojom::NetworkContextPtr
+mojo::Remote<::network::mojom::NetworkContext>
 HeadlessBrowserContextImpl::CreateNetworkContext(
     bool in_memory,
     const base::FilePath& relative_partition_path) {
diff --git a/headless/lib/browser/headless_browser_context_impl.h b/headless/lib/browser/headless_browser_context_impl.h
index 891a7e3f..bc4f0f05 100644
--- a/headless/lib/browser/headless_browser_context_impl.h
+++ b/headless/lib/browser/headless_browser_context_impl.h
@@ -21,6 +21,7 @@
 #include "headless/public/headless_browser.h"
 #include "headless/public/headless_browser_context.h"
 #include "headless/public/headless_export.h"
+#include "mojo/public/cpp/bindings/remote.h"
 
 namespace headless {
 class HeadlessBrowserImpl;
@@ -98,7 +99,7 @@
   const base::UnguessableToken* GetDevToolsFrameTokenForFrameTreeNodeId(
       int frame_tree_node_id) const;
 
-  ::network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<::network::mojom::NetworkContext> CreateNetworkContext(
       bool in_memory,
       const base::FilePath& relative_partition_path);
 
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc
index 069b516..7fff957 100644
--- a/headless/lib/browser/headless_content_browser_client.cc
+++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -291,7 +291,7 @@
   return browser_->options()->site_per_process;
 }
 
-::network::mojom::NetworkContextPtr
+mojo::Remote<::network::mojom::NetworkContext>
 HeadlessContentBrowserClient::CreateNetworkContext(
     content::BrowserContext* context,
     bool in_memory,
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h
index 31b2be1e..9a7ec3a 100644
--- a/headless/lib/browser/headless_content_browser_client.h
+++ b/headless/lib/browser/headless_content_browser_client.h
@@ -58,7 +58,7 @@
       std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
   bool ShouldEnableStrictSiteIsolation() override;
 
-  ::network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<::network::mojom::NetworkContext> CreateNetworkContext(
       content::BrowserContext* context,
       bool in_memory,
       const base::FilePath& relative_partition_path) override;
diff --git a/headless/lib/browser/headless_request_context_manager.cc b/headless/lib/browser/headless_request_context_manager.cc
index b3cb5ef..07adf5b 100644
--- a/headless/lib/browser/headless_request_context_manager.cc
+++ b/headless/lib/browser/headless_request_context_manager.cc
@@ -171,7 +171,7 @@
   network_service->ConfigureHttpAuthPrefs(std::move(auth_params));
 
   network_service->CreateNetworkContext(
-      mojo::MakeRequest(&manager->system_context_),
+      manager->system_context_.InitWithNewPipeAndPassReceiver(),
       manager->CreateNetworkContextParams(/* is_system = */ true));
 
   return manager;
@@ -208,13 +208,13 @@
     HeadlessProxyConfigMonitor::DeleteSoon(std::move(proxy_config_monitor_));
 }
 
-::network::mojom::NetworkContextPtr
+mojo::Remote<::network::mojom::NetworkContext>
 HeadlessRequestContextManager::CreateNetworkContext(
     bool in_memory,
     const base::FilePath& relative_partition_path) {
-  ::network::mojom::NetworkContextPtr network_context;
+  mojo::Remote<::network::mojom::NetworkContext> network_context;
   content::GetNetworkService()->CreateNetworkContext(
-      MakeRequest(&network_context),
+      network_context.BindNewPipeAndPassReceiver(),
       CreateNetworkContextParams(/* is_system = */ false));
   return network_context;
 }
diff --git a/headless/lib/browser/headless_request_context_manager.h b/headless/lib/browser/headless_request_context_manager.h
index b3012d5..01882ee 100644
--- a/headless/lib/browser/headless_request_context_manager.h
+++ b/headless/lib/browser/headless_request_context_manager.h
@@ -10,6 +10,8 @@
 #include "base/memory/ref_counted.h"
 #include "build/build_config.h"
 #include "content/public/browser/browser_context.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/network_service.mojom.h"
 
@@ -33,7 +35,7 @@
                                 base::FilePath user_data_path);
   ~HeadlessRequestContextManager();
 
-  ::network::mojom::NetworkContextPtr CreateNetworkContext(
+  mojo::Remote<::network::mojom::NetworkContext> CreateNetworkContext(
       bool in_memory,
       const base::FilePath& relative_partition_path);
 
@@ -53,7 +55,7 @@
   std::unique_ptr<net::ProxyConfig> proxy_config_;
   std::unique_ptr<HeadlessProxyConfigMonitor> proxy_config_monitor_;
 
-  ::network::mojom::NetworkContextPtr system_context_;
+  mojo::PendingRemote<::network::mojom::NetworkContext> system_context_;
   std::unique_ptr<content::ResourceContext> resource_context_;
 
   DISALLOW_COPY_AND_ASSIGN(HeadlessRequestContextManager);
diff --git a/headless/test/test_network_interceptor.cc b/headless/test/test_network_interceptor.cc
index 30f5df5..62f0df0 100644
--- a/headless/test/test_network_interceptor.cc
+++ b/headless/test/test_network_interceptor.cc
@@ -49,7 +49,8 @@
  private:
   void NotifyRedirect(const std::string& location) {
     auto redirect_info = net::RedirectInfo::ComputeRedirectInfo(
-        url_request_.method, url_request_.url, url_request_.site_for_cookies,
+        url_request_.method, url_request_.url, url_request_.request_initiator,
+        url_request_.site_for_cookies,
         net::URLRequest::FirstPartyURLPolicy::
             UPDATE_FIRST_PARTY_URL_ON_REDIRECT,
         url_request_.referrer_policy, url_request_.referrer.spec(),
diff --git a/ios/chrome/app/resources/BUILD.gn b/ios/chrome/app/resources/BUILD.gn
index 60c7a9a..f1f5c66 100644
--- a/ios/chrome/app/resources/BUILD.gn
+++ b/ios/chrome/app/resources/BUILD.gn
@@ -118,6 +118,7 @@
   public_deps = [
     ":launchscreen_app_logo",
     ":launchscreen_brand_name",
+    "//ios/chrome/common/colors/resources:background_color",
   ]
 }
 
diff --git a/ios/chrome/app/resources/LaunchScreen.xib b/ios/chrome/app/resources/LaunchScreen.xib
index 21fc220..e7beae23 100644
--- a/ios/chrome/app/resources/LaunchScreen.xib
+++ b/ios/chrome/app/resources/LaunchScreen.xib
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14845" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14865.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14799.2"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14819.2"/>
+        <capability name="Named colors" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -26,14 +27,14 @@
                         </constraints>
                     </imageView>
                     <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launchscreen_brand_name" translatesAutoresizingMaskIntoConstraints="NO" id="bAU-qs-X5w">
-                        <rect key="frame" x="153.5" y="807" width="107.00000000000003" height="35"/>
+                        <rect key="frame" x="153.5" y="807" width="107" height="35"/>
                         <constraints>
                             <constraint firstAttribute="width" constant="107" id="0Mf-i7-mvo"/>
                             <constraint firstAttribute="height" constant="35" id="7Gs-G7-OR2"/>
                         </constraints>
                     </imageView>
                 </subviews>
-                <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                <color key="backgroundColor" name="background_color"/>
                 <constraints>
                     <constraint firstItem="K7H-Iv-QNk" firstAttribute="width" secondItem="tRS-Cx-RH3" secondAttribute="width" multiplier="0.381966" id="3hJ-Yo-1Tg"/>
                     <constraint firstItem="K7H-Iv-QNk" firstAttribute="height" secondItem="tRS-Cx-RH3" secondAttribute="height" multiplier="0.381966" id="962-tL-cOd"/>
@@ -67,5 +68,8 @@
     <resources>
         <image name="launchscreen_app_logo" width="192" height="192"/>
         <image name="launchscreen_brand_name" width="107" height="35"/>
+        <namedColor name="background_color">
+            <color red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+        </namedColor>
     </resources>
 </document>
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h
index 93a6243..c06dcb4 100644
--- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h
+++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h
@@ -113,6 +113,7 @@
 // Secondary button title used to skip the sign-in.
 @property(nonatomic, readonly) NSString* skipSigninButtonTitle;
 
+@property(nonatomic, readonly) UIColor* backgroundColor;
 @property(nonatomic, readonly) UIButton* primaryButton;
 @property(nonatomic, readonly) UIButton* secondaryButton;
 
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
index 3179b2f..23273da 100644
--- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -308,7 +308,7 @@
 }
 
 - (void)setPrimaryButtonStyling:(MDCButton*)button {
-  UIColor* hintColor = UIColor.cr_systemBackgroundColor;
+  UIColor* hintColor = self.backgroundColor;
   UIColor* backgroundColor = [UIColor colorNamed:kBlueColor];
   UIColor* titleColor = [UIColor colorNamed:kSolidButtonTextColor];
 
@@ -331,8 +331,8 @@
 }
 
 - (void)setSecondaryButtonStyling:(MDCButton*)button {
-  UIColor* hintColor = UIColor.cr_systemBackgroundColor;
-  UIColor* backgroundColor = UIColor.cr_systemBackgroundColor;
+  UIColor* hintColor = self.backgroundColor;
+  UIColor* backgroundColor = self.backgroundColor;
   UIColor* titleColor = [UIColor colorNamed:kBlueColor];
 
   if (@available(iOS 13, *)) {
@@ -451,7 +451,7 @@
 }
 
 - (void)updateGradientColors {
-  UIColor* backgroundColor = UIColor.cr_systemBackgroundColor;
+  UIColor* backgroundColor = self.backgroundColor;
 
   if (@available(iOS 13, *)) {
     backgroundColor =
@@ -505,6 +505,10 @@
   return l10n_util::GetNSString(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SKIP_BUTTON);
 }
 
+- (UIColor*)backgroundColor {
+  return UIColor.cr_systemBackgroundColor;
+}
+
 - (UIButton*)primaryButton {
   return _primaryButton;
 }
@@ -815,7 +819,7 @@
 
 - (void)viewDidLoad {
   [super viewDidLoad];
-  self.view.backgroundColor = UIColor.cr_systemBackgroundColor;
+  self.view.backgroundColor = self.backgroundColor;
 
   _primaryButton = [[MDCFlatButton alloc] init];
   [self setPrimaryButtonStyling:_primaryButton];
diff --git a/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm b/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm
index f808600..48b8c23 100644
--- a/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm
@@ -16,6 +16,7 @@
 #import "ios/chrome/browser/ui/promos/signin_promo_view_controller.h"
 #include "ios/chrome/browser/ui/util/ui_util.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
+#import "ios/chrome/common/colors/semantic_color_names.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h"
@@ -120,6 +121,12 @@
                                                     }];
 }
 
+#pragma mark Superclass overrides
+
+- (UIColor*)backgroundColor {
+  return [UIColor colorNamed:kBackgroundColor];
+}
+
 #pragma mark ChromeSigninViewControllerDelegate
 
 - (void)willStartSignIn:(ChromeSigninViewController*)controller {
diff --git a/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm b/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm
index 40893f7..d9a85af 100644
--- a/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm
+++ b/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm
@@ -14,7 +14,6 @@
 #import "ios/chrome/browser/ui/util/label_observer.h"
 #include "ios/chrome/browser/ui/util/ui_util.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
-#import "ios/chrome/common/colors/UIColor+cr_semantic_colors.h"
 #import "ios/chrome/common/colors/semantic_color_names.h"
 #include "ios/chrome/common/string_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
@@ -165,7 +164,7 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    self.backgroundColor = UIColor.cr_systemBackgroundColor;
+    self.backgroundColor = [UIColor colorNamed:kBackgroundColor];
     self.autoresizingMask =
         UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
   }
@@ -224,7 +223,6 @@
 - (UIView*)containerView {
   if (!_containerView) {
     _containerView = [[UIView alloc] initWithFrame:CGRectZero];
-    [_containerView setBackgroundColor:UIColor.cr_systemBackgroundColor];
   }
   return _containerView;
 }
@@ -232,7 +230,6 @@
 - (UILabel*)titleLabel {
   if (!_titleLabel) {
     _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
-    [_titleLabel setBackgroundColor:UIColor.cr_systemBackgroundColor];
     [_titleLabel setNumberOfLines:0];
     [_titleLabel setLineBreakMode:NSLineBreakByWordWrapping];
     [_titleLabel setBaselineAdjustment:UIBaselineAdjustmentAlignBaselines];
@@ -246,7 +243,6 @@
   if (!_imageView) {
     UIImage* image = [UIImage imageNamed:kAppLogoImageName];
     _imageView = [[UIImageView alloc] initWithImage:image];
-    [_imageView setBackgroundColor:UIColor.cr_systemBackgroundColor];
   }
   return _imageView;
 }
diff --git a/ios/chrome/browser/ui/promos/BUILD.gn b/ios/chrome/browser/ui/promos/BUILD.gn
index 16121cf..b0499b10 100644
--- a/ios/chrome/browser/ui/promos/BUILD.gn
+++ b/ios/chrome/browser/ui/promos/BUILD.gn
@@ -18,6 +18,7 @@
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/ui/commands",
+    "//ios/chrome/common/colors",
     "//ios/public/provider/chrome/browser",
     "//ios/public/provider/chrome/browser/signin",
     "//net",
diff --git a/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm b/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm
index 3dec5b0..0a52f43 100644
--- a/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm
+++ b/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm
@@ -15,6 +15,7 @@
 #include "ios/chrome/browser/signin/authentication_service.h"
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
+#import "ios/chrome/common/colors/semantic_color_names.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h"
 #import "ios/public/provider/chrome/browser/signin/chrome_identity_service.h"
@@ -167,6 +168,12 @@
   return currentVersion;
 }
 
+#pragma mark Superclass overrides
+
+- (UIColor*)backgroundColor {
+  return [UIColor colorNamed:kBackgroundColor];
+}
+
 #pragma mark - PromoViewController
 
 + (BOOL)shouldBePresentedForBrowserState:
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h
index 3b294ae..7f71ede 100644
--- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h
+++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h
@@ -27,6 +27,11 @@
 
 - (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE;
 
+// Returns a view controller to be presented based on the camera state. Returns
+// |self| if the camera is available or an appropriate UIAlertController if
+// there was an error loading the camera.
+- (UIViewController*)getViewControllerToPresent;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_QR_SCANNER_QR_SCANNER_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm
index 164a179..010dbbf 100644
--- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm
+++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm
@@ -24,10 +24,6 @@
 using base::UserMetricsAction;
 
 @interface QRScannerViewController () {
-  // The scanned result.
-  NSString* _result;
-  // Whether the scanned result should be immediately loaded.
-  BOOL _loadResultImmediately;
   // The transitioning delegate used for presenting and dismissing the QR
   // scanner.
   ScannerTransitioningDelegate* _transitioningDelegate;
@@ -87,8 +83,8 @@
     // Post a notification announcing that a code was scanned. QR scanner will
     // be dismissed when the UIAccessibilityAnnouncementDidFinishNotification is
     // received.
-    _result = [result copy];
-    _loadResultImmediately = load;
+    self.result = [result copy];
+    self.loadResultImmediately = load;
     UIAccessibilityPostNotification(
         UIAccessibilityAnnouncementNotification,
         l10n_util::GetNSString(
@@ -103,4 +99,21 @@
   }
 }
 
+#pragma mark - Public methods
+
+- (UIViewController*)getViewControllerToPresent {
+  DCHECK(self.cameraController);
+  switch ([self.cameraController getAuthorizationStatus]) {
+    case AVAuthorizationStatusNotDetermined:
+    case AVAuthorizationStatusAuthorized:
+      _transitioningDelegate = [[ScannerTransitioningDelegate alloc] init];
+      [self setTransitioningDelegate:_transitioningDelegate];
+      return self;
+    case AVAuthorizationStatusRestricted:
+    case AVAuthorizationStatusDenied:
+      return scanner::DialogForCameraState(scanner::CAMERA_PERMISSION_DENIED,
+                                           nil);
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/ui/scanner/scanner_view_controller.h b/ios/chrome/browser/ui/scanner/scanner_view_controller.h
index da84e34..ebb80d0 100644
--- a/ios/chrome/browser/ui/scanner/scanner_view_controller.h
+++ b/ios/chrome/browser/ui/scanner/scanner_view_controller.h
@@ -37,6 +37,12 @@
 // Card scanner view.
 @property(nonatomic, readwrite) ScannerView* scannerView;
 
+// The scanned result.
+@property(nonatomic, strong) NSString* result;
+
+// Whether the scanned result should be immediately loaded.
+@property(nonatomic, assign) bool loadResultImmediately;
+
 // Stores the presentation provider.
 @property(nonatomic, readwrite, weak) id<ScannerPresenting>
     presentationProvider;
@@ -49,11 +55,6 @@
 
 - (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE;
 
-// Returns a view controller to be presented based on the camera state. Returns
-// |self| if the camera is available or an appropriate UIAlertController if
-// there was an error loading the camera.
-- (UIViewController*)getViewControllerToPresent;
-
 // Builds the scanner view. Must be overridden in the subclass.
 - (ScannerView*)buildScannerView;
 
diff --git a/ios/chrome/browser/ui/scanner/scanner_view_controller.mm b/ios/chrome/browser/ui/scanner/scanner_view_controller.mm
index baf6bd2..fab9b0b 100644
--- a/ios/chrome/browser/ui/scanner/scanner_view_controller.mm
+++ b/ios/chrome/browser/ui/scanner/scanner_view_controller.mm
@@ -24,14 +24,7 @@
 
 using base::UserMetricsAction;
 
-@interface ScannerViewController () {
-  // The scanned result.
-  NSString* _result;
-  // Whether the scanned result should be immediately loaded.
-  BOOL _loadResultImmediately;
-  // The transitioning delegate used for presenting and dismissing the scanner.
-  ScannerTransitioningDelegate* _transitioningDelegate;
-}
+@interface ScannerViewController ()
 
 @property(nonatomic, readwrite, weak) id<LoadQueryCommands> queryLoader;
 
@@ -160,21 +153,6 @@
 
 #pragma mark - public methods
 
-- (UIViewController*)getViewControllerToPresent {
-  DCHECK(self.cameraController);
-  switch ([self.cameraController getAuthorizationStatus]) {
-    case AVAuthorizationStatusNotDetermined:
-    case AVAuthorizationStatusAuthorized:
-      _transitioningDelegate = [[ScannerTransitioningDelegate alloc] init];
-      [self setTransitioningDelegate:_transitioningDelegate];
-      return self;
-    case AVAuthorizationStatusRestricted:
-    case AVAuthorizationStatusDenied:
-      return scanner::DialogForCameraState(scanner::CAMERA_PERMISSION_DENIED,
-                                           nil);
-  }
-}
-
 - (void)dismissForReason:(scannerViewController::DismissalReason)reason
           withCompletion:(void (^)(void))completion {
   [self.presentationProvider dismissScannerViewController:self
@@ -252,7 +230,7 @@
     [self dismissForReason:scannerViewController::SCAN_COMPLETE
             withCompletion:^{
               [self.queryLoader loadQuery:_result
-                              immediately:_loadResultImmediately];
+                              immediately:self.loadResultImmediately];
             }];
   }
 }
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 251193b..89bed63 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
@@ -54,6 +54,7 @@
 #import "ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #include "ios/chrome/common/channel_info.h"
+#import "ios/chrome/common/colors/semantic_color_names.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/public/provider/chrome/browser/chrome_browser_provider.h"
@@ -68,10 +69,7 @@
 // Maximum number of times to show a notice about other forms of browsing
 // history.
 const int kMaxTimesHistoryNoticeShown = 1;
-// The tableView button red background color.
-const CGFloat kTableViewButtonBackgroundColor = 0xE94235;
-// TableViewClearBrowsingDataItem's selectedBackgroundViewBackgroundColor.
-const int kSelectedBackgroundColorRGB = 0x4285F4;
+// TableViewClearBrowsingDataItem's selectedBackgroundViewBackgroundColorAlpha.
 const CGFloat kSelectedBackgroundColorAlpha = 0.05;
 
 // List of flags that have corresponding counters.
@@ -430,7 +428,7 @@
     collectionClearButtonItem.text =
         l10n_util::GetNSString(IDS_IOS_CLEAR_BUTTON);
     collectionClearButtonItem.accessibilityTraits |= UIAccessibilityTraitButton;
-    collectionClearButtonItem.textColor = [[MDCPalette cr_redPalette] tint500];
+    collectionClearButtonItem.textColor = [UIColor colorNamed:kRedColor];
     collectionClearButtonItem.accessibilityIdentifier =
         kClearBrowsingDataButtonIdentifier;
     clearButtonItem = collectionClearButtonItem;
@@ -441,7 +439,7 @@
     tableViewClearButtonItem.buttonText =
         l10n_util::GetNSString(IDS_IOS_CLEAR_BUTTON);
     tableViewClearButtonItem.buttonBackgroundColor =
-        UIColorFromRGB(kTableViewButtonBackgroundColor);
+        [UIColor colorNamed:kRedColor];
     tableViewClearButtonItem.buttonAccessibilityIdentifier =
         kClearBrowsingDataButtonIdentifier;
     clearButtonItem = tableViewClearButtonItem;
@@ -510,8 +508,9 @@
     tableViewClearDataItem.prefName = prefName;
     if (IsNewClearBrowsingDataUIEnabled()) {
       tableViewClearDataItem.useCustomSeparator = YES;
-      tableViewClearDataItem.checkedBackgroundColor = UIColorFromRGB(
-          kSelectedBackgroundColorRGB, kSelectedBackgroundColorAlpha);
+      tableViewClearDataItem.checkedBackgroundColor =
+          [[UIColor colorNamed:kBlueColor]
+              colorWithAlphaComponent:kSelectedBackgroundColorAlpha];
       tableViewClearDataItem.imageName = [_imageNamesByItemTypes
           objectForKey:[NSNumber numberWithInteger:itemType]];
       if (itemType == ItemTypeDataTypeCookiesSiteData) {
diff --git a/ios/chrome/browser/ui/settings/credit_card_scanner/BUILD.gn b/ios/chrome/browser/ui/settings/credit_card_scanner/BUILD.gn
index 007d49f..4c4c2da 100644
--- a/ios/chrome/browser/ui/settings/credit_card_scanner/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/credit_card_scanner/BUILD.gn
@@ -12,11 +12,13 @@
     "credit_card_scanner_camera_controller_delegate.h",
     "credit_card_scanner_coordinator.h",
     "credit_card_scanner_coordinator.mm",
+    "credit_card_scanner_image_processor.h",
+    "credit_card_scanner_image_processor.mm",
     "credit_card_scanner_mediator.h",
     "credit_card_scanner_mediator.mm",
     "credit_card_scanner_mediator_delegate.h",
-    "credit_card_scanner_mediator_util.h",
-    "credit_card_scanner_mediator_util.mm",
+    "credit_card_scanner_string_util.h",
+    "credit_card_scanner_string_util.mm",
     "credit_card_scanner_view.h",
     "credit_card_scanner_view.mm",
     "credit_card_scanner_view_controller.h",
@@ -42,7 +44,7 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
-    "credit_card_scanner_mediator_util_unittest.mm",
+    "credit_card_scanner_string_util_unittest.mm",
   ]
   deps = [
     "//ios/chrome/browser/ui/settings/credit_card_scanner",
diff --git a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_image_processor.h b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_image_processor.h
new file mode 100644
index 0000000..ac9a5b9
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_image_processor.h
@@ -0,0 +1,27 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_IMAGE_PROCESSOR_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_IMAGE_PROCESSOR_H_
+
+#import <Foundation/Foundation.h>
+
+#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanned_image_delegate.h"
+
+@protocol CreditCardConsumer;
+
+// A class process credit card images to recognise the text.
+API_AVAILABLE(ios(13.0))
+@interface CreditCardScannerImageProcessor
+    : NSObject <CreditCardScannedImageDelegate>
+
+// Initializes with Credit Card consumer.
+- (instancetype)initWithConsumer:(id<CreditCardConsumer>)creditCardConsumer
+    NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_IMAGE_PROCESSOR_H_
diff --git a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_image_processor.mm b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_image_processor.mm
new file mode 100644
index 0000000..25c9a46
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_image_processor.mm
@@ -0,0 +1,141 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_image_processor.h"
+
+#import <CoreMedia/CoreMedia.h>
+#import <Vision/Vision.h>
+
+#include "base/logging.h"
+#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_consumer.h"
+#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface CreditCardScannerImageProcessor ()
+
+// An image analysis request that finds and recognizes text in an image.
+@property(nonatomic, strong) VNRecognizeTextRequest* textRecognitionRequest;
+
+// This property is for an interface which notfies the credit card consumer.
+@property(nonatomic, weak) id<CreditCardConsumer> creditCardConsumer;
+
+// The card number set after |textRecognitionRequest| from recognised text on
+// the card.
+@property(nonatomic, strong) NSString* cardNumber;
+
+// The card expiration month set after |textRecognitionRequest| from recognised
+// text on the card.
+@property(nonatomic, strong) NSString* expirationMonth;
+
+// The card expiration year set after |textRecognitionRequest| from recognised
+// text on the card.
+@property(nonatomic, strong) NSString* expirationYear;
+
+@end
+
+@implementation CreditCardScannerImageProcessor
+
+#pragma mark - Lifecycle
+
+- (instancetype)initWithConsumer:(id<CreditCardConsumer>)creditCardConsumer {
+  self = [super init];
+  if (self) {
+    _creditCardConsumer = creditCardConsumer;
+  }
+  return self;
+}
+
+#pragma mark - CreditCardScannerImageDelegate
+
+- (void)processOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
+                         viewport:(CGRect)viewport {
+  // Current thread is unknown background thread as is a callback from UIKit.
+  DCHECK(!NSThread.isMainThread);
+  if (!self.textRecognitionRequest) {
+    __weak __typeof(self) weakSelf = self;
+
+    auto completionHandler = ^(VNRequest* request, NSError* error) {
+      if (request.results.count != 0) {
+        [weakSelf searchInRecognizedText:request.results];
+      }
+    };
+
+    self.textRecognitionRequest = [[VNRecognizeTextRequest alloc]
+        initWithCompletionHandler:completionHandler];
+
+    // Sets the region of interest of the request to the scanner viewport to
+    // focus on the scan area. This improves performance by ignoring irrelevant
+    // background text.
+    self.textRecognitionRequest.regionOfInterest = viewport;
+    // Fast option doesn't recognise card number correctly.
+    self.textRecognitionRequest.recognitionLevel =
+        VNRequestTextRecognitionLevelAccurate;
+    // For time performance as we scan for numbers and date only.
+    self.textRecognitionRequest.usesLanguageCorrection = false;
+  }
+
+  CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
+  DCHECK(pixelBuffer);
+
+  NSMutableDictionary* options = [[NSMutableDictionary alloc] init];
+  VNImageRequestHandler* handler =
+      [[VNImageRequestHandler alloc] initWithCVPixelBuffer:pixelBuffer
+                                                   options:options];
+
+  NSError* requestError;
+  [handler performRequests:@[ self.textRecognitionRequest ]
+                     error:&requestError];
+
+  // Error code 11 is unknown exception. It happens for some frames.
+  DCHECK(!requestError || requestError.code == 11);
+}
+
+#pragma mark - Helper Methods
+
+// Searches in |recognizedText| for credit card number and expiration date.
+- (void)searchInRecognizedText:
+    (NSArray<VNRecognizedTextObservation*>*)recognizedText {
+  // Current thread is unknown background thread as is a callback from UIKit.
+  DCHECK(!NSThread.isMainThread);
+  NSUInteger maximumCandidates = 1;
+
+  for (VNRecognizedTextObservation* observation in recognizedText) {
+    VNRecognizedText* candidate =
+        [[observation topCandidates:maximumCandidates] firstObject];
+    if (candidate == nil) {
+      continue;
+    }
+    [self extractDataFromText:candidate.string];
+  }
+
+  if (self.cardNumber) {
+    // Send the result to the main thread.
+    dispatch_async(dispatch_get_main_queue(), ^{
+      [self.creditCardConsumer setCreditCardNumber:self.cardNumber
+                                   expirationMonth:self.expirationMonth
+                                    expirationYear:self.expirationYear];
+    });
+  }
+}
+
+// Checks the type of |text| to assign it to appropriate property.
+- (void)extractDataFromText:(NSString*)text {
+  if (!self.expirationMonth || !self.expirationYear) {
+    NSDateComponents* components = ios::ExtractExpirationDateFromText(text);
+
+    if (components) {
+      self.expirationMonth = [@([components month]) stringValue];
+      self.expirationYear = [@([components year]) stringValue];
+    }
+  }
+
+  if (!self.cardNumber) {
+    self.cardNumber = ios::ExtractCreditCardNumber(text);
+  }
+}
+
+@end
diff --git a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.h b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.h
index 39c613e..c263ac4 100644
--- a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.h
+++ b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.h
@@ -7,14 +7,15 @@
 
 #import <UIKit/UIKit.h>
 
+#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_consumer.h"
 #import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanned_image_delegate.h"
 
-@protocol CreditCardConsumer;
 @protocol CreditCardScannerMediatorDelegate;
 
 // A mediator for CreditCardScanner which manages processing images.
 API_AVAILABLE(ios(13.0))
-@interface CreditCardScannerMediator : NSObject <CreditCardScannedImageDelegate>
+@interface CreditCardScannerMediator
+    : NSObject <CreditCardConsumer, CreditCardScannedImageDelegate>
 
 // Initializes with Credit Card mediator delegate and Credit Card consumer.
 - (instancetype)initWithDelegate:(id<CreditCardScannerMediatorDelegate>)
diff --git a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.mm b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.mm
index cd52ed8..99fc1757 100644
--- a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.mm
+++ b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.mm
@@ -4,15 +4,10 @@
 
 #import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator.h"
 
-#import <CoreMedia/CoreMedia.h>
-#import <Vision/Vision.h>
-
-#include "base/logging.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
-#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_consumer.h"
+#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_image_processor.h"
 #import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_delegate.h"
-#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -22,9 +17,6 @@
 
 @interface CreditCardScannerMediator ()
 
-// An image analysis request that finds and recognizes text in an image.
-@property(nonatomic, strong) VNRecognizeTextRequest* textRecognitionRequest;
-
 // Delegate notified when a card has been scanned.
 @property(nonatomic, weak) id<CreditCardScannerMediatorDelegate>
     creditCardScannerMediatorDelegate;
@@ -44,6 +36,10 @@
 // text on the card.
 @property(nonatomic, strong) NSString* expirationYear;
 
+// Object to Perform image processing and return the text on the image.
+@property(nonatomic, strong)
+    CreditCardScannerImageProcessor* creditCardImageScanner;
+
 @end
 
 @implementation CreditCardScannerMediator
@@ -57,7 +53,10 @@
   if (self) {
     _creditCardScannerMediatorDelegate = creditCardScannerMediatorDelegate;
     _creditCardConsumer = creditCardConsumer;
+    _creditCardImageScanner =
+        [[CreditCardScannerImageProcessor alloc] initWithConsumer:self];
   }
+
   return self;
 }
 
@@ -65,46 +64,22 @@
 
 - (void)processOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
                          viewport:(CGRect)viewport {
-  if (!self.textRecognitionRequest) {
-    __weak __typeof(self) weakSelf = self;
+  // Current thread is unknown background thread as is a callback from UIKit.
+  DCHECK(!NSThread.isMainThread);
+  [self.creditCardImageScanner processOutputSampleBuffer:sampleBuffer
+                                                viewport:viewport];
+}
 
-    auto completionHandler = ^(VNRequest* request, NSError* error) {
-      if (request.results.count != 0) {
-        [weakSelf searchInRecognizedText:request.results];
-        if (self.cardNumber) {
-          [self dismissScannerOnCardScanned];
-        }
-      }
-    };
+#pragma mark - CreditCardConsumer
 
-    self.textRecognitionRequest = [[VNRecognizeTextRequest alloc]
-        initWithCompletionHandler:completionHandler];
-
-    // Sets the region of interest of the request to the scanner viewport to
-    // focus on the scan area. This improves performance by ignoring irrelevant
-    // background text.
-    self.textRecognitionRequest.regionOfInterest = viewport;
-    // Fast option doesn't recognise card number correctly.
-    self.textRecognitionRequest.recognitionLevel =
-        VNRequestTextRecognitionLevelAccurate;
-    // For time performance as we scan for numbers and date only.
-    self.textRecognitionRequest.usesLanguageCorrection = false;
-  }
-
-  CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
-  DCHECK(pixelBuffer);
-
-  NSMutableDictionary* options = [[NSMutableDictionary alloc] init];
-  VNImageRequestHandler* handler =
-      [[VNImageRequestHandler alloc] initWithCVPixelBuffer:pixelBuffer
-                                                   options:options];
-
-  NSError* requestError;
-  [handler performRequests:@[ self.textRecognitionRequest ]
-                     error:&requestError];
-
-  // Error code 11 is unknown exception. It happens for some frames.
-  DCHECK(!requestError || requestError.code == 11);
+- (void)setCreditCardNumber:(NSString*)cardNumber
+            expirationMonth:(NSString*)expirationMonth
+             expirationYear:(NSString*)expirationYear {
+  [self.creditCardConsumer setCreditCardNumber:cardNumber
+                               expirationMonth:expirationMonth
+                                expirationYear:expirationYear];
+  self.creditCardImageScanner = nil;
+  [self dismissScannerOnCardScanned];
 }
 
 #pragma mark - Helper Methods
@@ -116,40 +91,4 @@
       creditCardScannerMediatorDidFinishScan:self];
 }
 
-// Searches in |recognizedText| for credit card number and expiration date.
-- (void)searchInRecognizedText:
-    (NSArray<VNRecognizedTextObservation*>*)recognizedText {
-  NSUInteger maximumCandidates = 1;
-
-  for (VNRecognizedTextObservation* observation in recognizedText) {
-    VNRecognizedText* candidate =
-        [[observation topCandidates:maximumCandidates] firstObject];
-    if (candidate == nil) {
-      continue;
-    }
-    [self extractDataFromText:candidate.string];
-  }
-
-  if (self.cardNumber) {
-    [self.creditCardConsumer setCreditCardNumber:self.cardNumber
-                                 expirationMonth:self.expirationMonth
-                                  expirationYear:self.expirationYear];
-    [self.creditCardScannerMediatorDelegate
-        creditCardScannerMediatorDidFinishScan:self];
-  }
-}
-
-// Checks the type of |text| to assign it to appropriate property.
-- (void)extractDataFromText:(NSString*)text {
-  NSDateComponents* components = ios::ExtractExpirationDateFromText(text);
-
-  if (components) {
-    self.expirationMonth = [@([components month]) stringValue];
-    self.expirationYear = [@([components year]) stringValue];
-  }
-  if (!self.cardNumber) {
-    self.cardNumber = ios::ExtractCreditCardNumber(text);
-  }
-}
-
 @end
diff --git a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.h b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.h
similarity index 89%
rename from ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.h
rename to ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.h
index ad66d3d..e8d4ee6 100644
--- a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.h
+++ b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_MEDIATOR_UTIL_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_MEDIATOR_UTIL_H_
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_STRING_UTIL_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_STRING_UTIL_H_
 
 #import <Foundation/Foundation.h>
 
@@ -21,4 +21,4 @@
 
 }  // namespace ios
 
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_MEDIATOR_UTIL_H_
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CREDIT_CARD_SCANNER_CREDIT_CARD_SCANNER_STRING_UTIL_H_
diff --git a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.mm b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.mm
similarity index 98%
rename from ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.mm
rename to ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.mm
index 27f2693..bebcd9a6 100644
--- a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.mm
+++ b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.h"
+#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util_unittest.mm b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util_unittest.mm
similarity index 85%
rename from ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util_unittest.mm
rename to ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util_unittest.mm
index 9dde204..bdce3a2 100644
--- a/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util_unittest.mm
+++ b/ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_mediator_util.h"
+#import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_string_util.h"
 
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -11,12 +11,12 @@
 #error "This file requires ARC support."
 #endif
 
-using CreditCardScannerMediatorUtilTest = PlatformTest;
+using CreditCardScannerStringUtilUnitTest = PlatformTest;
 
 #pragma mark - Test ExtractExpirationDateFromText
 
 // Tests extracting month and year from valid date text.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractExpirationDateFromValidDateText) {
   NSDateComponents* components = ios::ExtractExpirationDateFromText(@"10/25");
 
@@ -25,7 +25,7 @@
 }
 
 // Tests extracting month and year from invalid date text.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractExpirationDateFromInvalidDateText) {
   NSDateComponents* components = ios::ExtractExpirationDateFromText(@"13/888");
 
@@ -33,7 +33,7 @@
 }
 
 // Tests extracting month and year from invalid text.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractExpirationDateFromInvalidText) {
   NSDateComponents* components = ios::ExtractExpirationDateFromText(@"aaaaa");
 
@@ -41,7 +41,7 @@
 }
 
 // Tests extracting month and year from invalid text with correct format.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractExpirationDateFromInvalidFormattedText) {
   NSDateComponents* components = ios::ExtractExpirationDateFromText(@"aa/aa");
 
@@ -51,7 +51,7 @@
 #pragma mark - Test ExtractCreditCardNumber
 
 // Tests extracting card number from valid card number text (16 digits).
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractCardNumberFromValidCreditCardNumber16Digits) {
   NSString* cardNumber = ios::ExtractCreditCardNumber(@"4111111111111111");
 
@@ -59,7 +59,7 @@
 }
 
 // Tests extracting card number from valid card number text (14 digits).
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractCardNumberFromValidCreditCardNumber14Digits) {
   NSString* cardNumber = ios::ExtractCreditCardNumber(@"4111111111111");
 
@@ -68,7 +68,7 @@
 
 // Tests extracting card number from valid card number text contains wrong
 // characters.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractCardNumberFromValidCreditCardNumberWithWrongCharacters) {
   NSString* cardNumber = ios::ExtractCreditCardNumber(@"41/11-1111 1111.11:11");
 
@@ -77,7 +77,7 @@
 
 // Tests extracting card number from text after converting
 // illegal characters.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractCardNumberFromValidCreditCardNumberAfterConversion) {
   NSString* cardNumber = ios::ExtractCreditCardNumber(@"41b1C1g1D1i1L1z1");
 
@@ -85,7 +85,7 @@
 }
 
 // Tests extracting card number from invalid card number text (10 digits).
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractCardNumberFromInvalidCreditCardNumber10Digits) {
   NSString* cardNumber = ios::ExtractCreditCardNumber(@"4111111111");
 
@@ -93,7 +93,7 @@
 }
 
 // Tests extracting card number from invalid card number text.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestExtractCardNumberFromInvalidCreditCardNumber) {
   NSString* cardNumber = ios::ExtractCreditCardNumber(@"4111a11b11c11");
 
@@ -103,7 +103,7 @@
 #pragma mark - Test SubstituteSimilarCharactersInRecognizedText
 
 // Tests substituting convertible characters with digits.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestSubstitutingTrueCharactersWithDigits) {
   NSString* number =
       ios::SubstituteSimilarCharactersInRecognizedText(@"bCdGiLoQsTuZ");
@@ -112,7 +112,7 @@
 }
 
 // Tests substituting text without characters with digits.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestSubstitutingTextWithoutCharacters) {
   NSString* number =
       ios::SubstituteSimilarCharactersInRecognizedText(@"4111111111111111");
@@ -121,7 +121,7 @@
 }
 
 // Tests substituting inconvertible characters with digits.
-TEST_F(CreditCardScannerMediatorUtilTest,
+TEST_F(CreditCardScannerStringUtilUnitTest,
        TestSubstitutingFalseCharactersWithDigits) {
   NSString* cardNumber =
       ios::SubstituteSimilarCharactersInRecognizedText(@"abcdefghi");
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
index 9a4a9a57..f5be4bc 100644
--- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
+++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
@@ -137,8 +137,7 @@
 
 // Tests that signing out of a managed account from the Settings works
 // correctly.
-// TODO(crbug.com/929967): Re-enable the test.
-- (void)DISABLED_testSignInDisconnectFromChromeManaged {
+- (void)testSignInDisconnectFromChromeManaged {
   ChromeIdentity* identity = [SigninEarlGreyUtils fakeManagedIdentity];
   ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity(
       identity);
@@ -146,7 +145,7 @@
   [ChromeEarlGreyUI openSettingsMenu];
   [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()];
   [SigninEarlGreyUI selectIdentityWithEmail:identity.userEmail];
-
+  [SigninEarlGreyUI confirmSigninConfirmationDialog];
   {
     // Synchronization off due to an infinite spinner.
     ScopedSynchronizationDisabler disabler;
@@ -154,9 +153,9 @@
         IDS_IOS_MANAGED_SIGNIN_ACCEPT_BUTTON));
     TapButtonWithLabelId(IDS_IOS_MANAGED_SIGNIN_ACCEPT_BUTTON);
   }
-
-  [SigninEarlGreyUI confirmSigninConfirmationDialog];
   [SigninEarlGreyUtils checkSignedInWithIdentity:identity];
+  [[EarlGrey selectElementWithMatcher:SettingsDoneButton()]
+      performAction:grey_tap()];
 
   // Sign out.
   [SigninEarlGreyUI signOutWithManagedAccount:YES];
diff --git a/jingle/glue/network_service_config_test_util.cc b/jingle/glue/network_service_config_test_util.cc
index aeb01de..131b6ed 100644
--- a/jingle/glue/network_service_config_test_util.cc
+++ b/jingle/glue/network_service_config_test_util.cc
@@ -24,7 +24,7 @@
   mojo_runner_ = base::SequencedTaskRunnerHandle::Get();
   if (net_runner_->BelongsToCurrentThread()) {
     CreateNetworkContextOnNetworkRunner(
-        mojo::MakeRequest(&network_context_ptr_), nullptr);
+        network_context_remote_.BindNewPipeAndPassReceiver(), nullptr);
   } else {
     base::ScopedAllowBaseSyncPrimitivesForTesting permission;
     base::WaitableEvent wait_for_create;
@@ -32,7 +32,8 @@
         FROM_HERE,
         base::BindOnce(
             &NetworkServiceConfigTestUtil::CreateNetworkContextOnNetworkRunner,
-            base::Unretained(this), mojo::MakeRequest(&network_context_ptr_),
+            base::Unretained(this),
+            network_context_remote_.BindNewPipeAndPassReceiver(),
             &wait_for_create));
     // Block for creation to avoid needing to worry about
     // CreateNetworkContextOnNetworkRunner
@@ -96,7 +97,7 @@
     instance->network_context_getter_.Run()->CreateProxyResolvingSocketFactory(
         std::move(request));
   } else {
-    instance->network_context_ptr_->CreateProxyResolvingSocketFactory(
+    instance->network_context_remote_->CreateProxyResolvingSocketFactory(
         std::move(request));
   }
 }
diff --git a/jingle/glue/network_service_config_test_util.h b/jingle/glue/network_service_config_test_util.h
index a40eb12..428fe32 100644
--- a/jingle/glue/network_service_config_test_util.h
+++ b/jingle/glue/network_service_config_test_util.h
@@ -10,6 +10,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "jingle/glue/network_service_config.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "services/network/network_context.h"
 #include "services/network/public/mojom/network_context.mojom.h"
@@ -69,8 +70,8 @@
   NetworkContextGetter network_context_getter_;
   std::unique_ptr<network::NetworkContext>
       network_context_;  // lives on |net_runner_|
-  network::mojom::NetworkContextPtr
-      network_context_ptr_;  // lives on |mojo_runner_|
+  mojo::Remote<network::mojom::NetworkContext>
+      network_context_remote_;  // lives on |mojo_runner_|
   base::WeakPtrFactory<NetworkServiceConfigTestUtil> weak_ptr_factory_{
       this};  // lives on |mojo_runner_|
 };
diff --git a/net/docs/certificate-transparency.md b/net/docs/certificate-transparency.md
index 9a47427..ed0d5436 100644
--- a/net/docs/certificate-transparency.md
+++ b/net/docs/certificate-transparency.md
@@ -218,7 +218,7 @@
 trusted for users in their Enterprise.
 
 Finally, organizations may manage their own PKI in-house, using CA
-software such as [CFSSL](https://github.com/cloudflare/cfssl), [Boulder](https://github.com/letsencrypt/boulder), 
+software such as [CFSSL](https://github.com/cloudflare/cfssl), [Boulder](https://github.com/letsencrypt/boulder),
 [EJBCA](https://www.ejbca.org/) or
 [Active Directory Certificate Services](https://msdn.microsoft.com/en-us/library/ff630887.aspx).
 Managing certificates in-house may be more complex and security risky, but
@@ -256,12 +256,12 @@
 Several Chrome-specific policies exist that allow Enterprises to configure
 their machines or users to disable Certificate Transparency for certain cases.
 These policies are documented in the
-[master policy list](https://www.chromium.org/administrators/policy-list-3),
+[master policy list](https://cloud.google.com/docs/chrome-enterprise/policies),
 but detailed further below.
 
 #### CertificateTransparencyEnforcementDisabledForUrls
 
-This [policy](https://www.chromium.org/administrators/policy-list-3#CertificateTransparencyEnforcementDisabledForUrls)
+This [policy](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=CertificateTransparencyEnforcementDisabledForUrls)
 has been available since Chrome 53, and allows for disabling Certificate
 Transparency enforcement for a certain set of domains or subdomains, without
 disabling Certificate Transparency altogether.
@@ -277,7 +277,7 @@
 
 #### CertificateTransparencyEnforcementDisabledForCas
 
-This [policy](https://www.chromium.org/administrators/policy-list-3#CertificateTransparencyEnforcementDisabledForCas),
+This [policy](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=CertificateTransparencyEnforcementDisabledForCas),
 available since Chrome 57, allows for disabling Certificate Transparency
 enforcement if certain conditions are met in the trusted certificate chain.
 This allows disabling CT without having to list all of the domain names, but
@@ -307,7 +307,7 @@
 
 #### CertificateTransparencyEnforcementDisabledForLegacyCas
 
-This [policy](https://www.chromium.org/administrators/policy-list-3#CertificateTransparencyEnforcementDisabledForLegacyCas),
+This [policy](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=CertificateTransparencyEnforcementDisabledForLegacyCas),
 available since Chrome 67, allows for disabling Certificate Transparency
 enforcement for certain legacy CAs that have not adopted modern security and
 audit requirements required of publicly-trusted CAs. This is particularly
diff --git a/net/url_request/redirect_info.cc b/net/url_request/redirect_info.cc
index d716a0c1..dbdbc008 100644
--- a/net/url_request/redirect_info.cc
+++ b/net/url_request/redirect_info.cc
@@ -117,6 +117,7 @@
 RedirectInfo RedirectInfo::ComputeRedirectInfo(
     const std::string& original_method,
     const GURL& original_url,
+    const base::Optional<url::Origin>& initiator,
     const GURL& original_site_for_cookies,
     URLRequest::FirstPartyURLPolicy original_first_party_url_policy,
     URLRequest::ReferrerPolicy original_referrer_policy,
@@ -166,9 +167,9 @@
 
   // Alter the referrer if redirecting cross-origin (especially HTTP->HTTPS).
   redirect_info.new_referrer =
-      URLRequestJob::ComputeReferrerForPolicy(redirect_info.new_referrer_policy,
-                                              GURL(original_referrer),
-                                              redirect_info.new_url)
+      URLRequestJob::ComputeReferrerForPolicy(
+          redirect_info.new_referrer_policy, GURL(original_referrer),
+          initiator.value_or(url::Origin()), redirect_info.new_url)
           .spec();
 
   return redirect_info;
diff --git a/net/url_request/redirect_info.h b/net/url_request/redirect_info.h
index 3e4699f..ea8febe7 100644
--- a/net/url_request/redirect_info.h
+++ b/net/url_request/redirect_info.h
@@ -27,6 +27,7 @@
       // request.
       const std::string& original_method,
       const GURL& original_url,
+      const base::Optional<url::Origin>& initiator,
       const GURL& original_site_for_cookies,
       URLRequest::FirstPartyURLPolicy original_first_party_url_policy,
       URLRequest::ReferrerPolicy original_referrer_policy,
diff --git a/net/url_request/redirect_info_unittest.cc b/net/url_request/redirect_info_unittest.cc
index d92e688..f9d4538 100644
--- a/net/url_request/redirect_info_unittest.cc
+++ b/net/url_request/redirect_info_unittest.cc
@@ -47,7 +47,8 @@
                  << " http_status_code: " << test.http_status_code);
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        test.original_method, kOriginalUrl, kOriginalSiteForCookies,
+        test.original_method, kOriginalUrl,
+        url::Origin::Create(kOriginalSiteForCookies), kOriginalSiteForCookies,
         kOriginalFirstPartyUrlPolicy, kOriginalReferrerPolicy,
         kOriginalReferrer, test.http_status_code, kNewLocation,
         base::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
@@ -98,7 +99,8 @@
                  << " new_location: " << test.new_location);
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        KOriginalMethod, GURL(test.original_url), kOriginalSiteForCookies,
+        KOriginalMethod, GURL(test.original_url),
+        url::Origin::Create(kOriginalSiteForCookies), kOriginalSiteForCookies,
         kOriginalFirstPartyUrlPolicy, kOriginalReferrerPolicy,
         kOriginalReferrer, kHttpStatusCode, GURL(test.new_location),
         base::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
@@ -136,7 +138,8 @@
                  << static_cast<int>(test.original_first_party_url_policy));
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        KOriginalMethod, kOriginalUrl, kOriginalSiteForCookies,
+        KOriginalMethod, kOriginalUrl,
+        url::Origin::Create(kOriginalSiteForCookies), kOriginalSiteForCookies,
         test.original_first_party_url_policy, kOriginalReferrerPolicy,
         kOriginalReferrer, kHttpStatusCode, kNewLocation,
         base::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
@@ -237,7 +240,8 @@
            ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected new policy */,
        "https://foo.test/referrer" /* expected new referrer */},
 
-      // ... but should be stripped to the origin for a cross-origin redirect.
+      // ... but should be stripped to the origin for a cross-origin redirect
+      // ...
       {"https://foo.test/one" /* original url */,
        "https://foo.test/one" /* original referrer */,
        "Location: https://bar.test/two\n"
@@ -247,6 +251,16 @@
            ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected new policy */,
        "https://foo.test/" /* expected new referrer */},
 
+      // ... even when the referrer is same-origin with the redirect.
+      {"https://foo.test/one" /* original url */,
+       "https://bar.test/one" /* original referrer */,
+       "Location: https://bar.test/two\n"
+       "Referrer-Policy: origin-when-cross-origin\n",
+       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
+       URLRequest::
+           ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected new policy */,
+       "https://bar.test/" /* expected new referrer */},
+
       // If a redirect serves 'Referrer-Policy: same-origin', then the referrer
       // should be untouched for a same-origin redirect,
       {"https://foo.test/one" /* original url */,
@@ -258,7 +272,7 @@
        ,
        "https://foo.test/referrer" /* expected new referrer */},
 
-      // ... but should be cleared for a cross-origin redirect.
+      // ... but should be cleared for a cross-origin redirect ...
       {"https://foo.test/one" /* original url */,
        "https://foo.test/referrer" /* original referrer */,
        "Location: https://bar.test/two\n"
@@ -267,6 +281,15 @@
        URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN,
        "" /* expected new referrer */},
 
+      // ... even when the referrer is same-origin with the redirect ...
+      {"https://foo.test/one" /* original url */,
+       "https://bar.test/referrer" /* original referrer */,
+       "Location: https://bar.test/two\n"
+       "Referrer-Policy: same-origin\n",
+       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
+       URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN,
+       "" /* expected new referrer */},
+
       // If a redirect serves 'Referrer-Policy: strict-origin', then the
       // referrer should be the origin only for a cross-origin non-downgrading
       // redirect,
@@ -285,6 +308,22 @@
        URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
        "http://foo.test/" /* expected new referrer */},
 
+      // even when the referrer is same-origin with the redirect ...
+      {"https://foo.test/one" /* original url */,
+       "https://bar.test/referrer" /* original referrer */,
+       "Location: https://bar.test/two\n"
+       "Referrer-Policy: strict-origin\n",
+       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
+       URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+       "https://bar.test/" /* expected new referrer */},
+      {"http://foo.test/one" /* original url */,
+       "http://bar.test/referrer" /* original referrer */,
+       "Location: http://bar.test/two\n"
+       "Referrer-Policy: strict-origin\n",
+       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
+       URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+       "http://bar.test/" /* expected new referrer */},
+
       // ... but should be cleared for a downgrading redirect.
       {"https://foo.test/one" /* original url */,
        "https://foo.test/referrer" /* original referrer */,
@@ -329,6 +368,22 @@
        URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
        "http://foo.test/" /* expected new referrer */},
 
+      // ... even when the referrer is same-origin with the redirect ...
+      {"https://foo.test/one" /* original url */,
+       "https://bar.test/referrer" /* original referrer */,
+       "Location: https://bar.test/two\n"
+       "Referrer-Policy: strict-origin-when-cross-origin\n",
+       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
+       URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+       "https://bar.test/" /* expected new referrer */},
+      {"http://foo.test/one" /* original url */,
+       "http://bar.test/referrer" /* original referrer */,
+       "Location: http://bar.test/two\n"
+       "Referrer-Policy: strict-origin-when-cross-origin\n",
+       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
+       URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+       "http://bar.test/" /* expected new referrer */},
+
       // ... and should be cleared for a downgrading redirect.
       {"https://foo.test/one" /* original url */,
        "https://foo.test/referrer" /* original referrer */,
@@ -397,6 +452,14 @@
        URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
        URLRequest::ORIGIN /* expected new policy */,
        "https://foo.test/" /* expected new referrer */},
+      {"https://foo.test/one" /* original url */,
+       "https://bar.test/one" /* original referrer */,
+       "Location: https://bar.test/two\n"
+       "Referrer-Policy: unsafe-url\n"
+       "Referrer-Policy: origin\n",
+       URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
+       URLRequest::ORIGIN /* expected new policy */,
+       "https://bar.test/" /* expected new referrer */},
 
       // An empty header should not affect the request.
       {"https://foo.test/one" /* original url */,
@@ -449,9 +512,10 @@
     const GURL new_location = original_url.Resolve(location_string);
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        KOriginalMethod, original_url, kOriginalSiteForCookies,
-        kOriginalFirstPartyUrlPolicy, test.original_referrer_policy,
-        test.original_referrer, response_headers->response_code(), new_location,
+        KOriginalMethod, original_url, url::Origin::Create(original_url),
+        kOriginalSiteForCookies, kOriginalFirstPartyUrlPolicy,
+        test.original_referrer_policy, test.original_referrer,
+        response_headers->response_code(), new_location,
         RedirectUtil::GetReferrerPolicyHeader(response_headers.get()),
         kInsecureSchemeWasUpgraded, kCopyFragment);
 
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index 292df77..3e588518 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -678,7 +678,8 @@
 
   GURL referrer_url(referrer_);
   if (referrer_url != URLRequestJob::ComputeReferrerForPolicy(
-                          referrer_policy_, referrer_url, url())) {
+                          referrer_policy_, referrer_url,
+                          initiator_.value_or(url::Origin()), url())) {
     if (!network_delegate_ ||
         !network_delegate_->CancelURLRequestWithPolicyViolatingReferrerHeader(
             *this, url(), referrer_url)) {
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 88b93f7..9bf5a4f 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -275,16 +275,19 @@
   out->clear();
 }
 
+// When making changes to this method that affect the returned referrer value,
+// also update blink::SecurityPolicy::GenerateReferrer accordingly.
 // static
 GURL URLRequestJob::ComputeReferrerForPolicy(URLRequest::ReferrerPolicy policy,
                                              const GURL& original_referrer,
+                                             const url::Origin& initiator,
                                              const GURL& destination) {
   bool secure_referrer_but_insecure_destination =
       original_referrer.SchemeIsCryptographic() &&
       !destination.SchemeIsCryptographic();
   url::Origin referrer_origin = url::Origin::Create(original_referrer);
   bool same_origin =
-      referrer_origin.IsSameOriginWith(url::Origin::Create(destination));
+      initiator.IsSameOriginWith(url::Origin::Create(destination));
   switch (policy) {
     case URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE:
       return secure_referrer_but_insecure_destination ? GURL()
@@ -391,9 +394,10 @@
     base::WeakPtr<URLRequestJob> weak_this(weak_factory_.GetWeakPtr());
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        request_->method(), request_->url(), request_->site_for_cookies(),
-        request_->first_party_url_policy(), request_->referrer_policy(),
-        request_->referrer(), http_status_code, new_location,
+        request_->method(), request_->url(), request_->initiator(),
+        request_->site_for_cookies(), request_->first_party_url_policy(),
+        request_->referrer_policy(), request_->referrer(), http_status_code,
+        new_location,
         net::RedirectUtil::GetReferrerPolicyHeader(
             request_->response_headers()),
         insecure_scheme_was_upgraded, CopyFragmentOnRedirect(new_location));
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
index 68a36ec..9519c6d 100644
--- a/net/url_request/url_request_job.h
+++ b/net/url_request/url_request_job.h
@@ -246,10 +246,11 @@
   // from the remote party with the actual response headers recieved.
   virtual void SetResponseHeadersCallback(ResponseHeadersCallback callback) {}
 
-  // Given |policy|, |referrer|, and |destination|, returns the
+  // Given |policy|, |referrer|, |initiator|, and |destination|, returns the
   // referrer URL mandated by |request|'s referrer policy.
   static GURL ComputeReferrerForPolicy(URLRequest::ReferrerPolicy policy,
                                        const GURL& original_referrer,
+                                       const url::Origin& initiator,
                                        const GURL& destination);
 
  protected:
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 84bba55..50100cc 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -8635,6 +8635,7 @@
     TestDelegate d;
     std::unique_ptr<URLRequest> req(default_context().CreateRequest(
         origin_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+    req->set_initiator(url::Origin::Create(origin_url));
     req->set_referrer_policy(policy);
     req->SetReferrer(referrer.spec());
     req->Start();
@@ -8654,6 +8655,9 @@
   }
 
   EmbeddedTestServer* origin_server() const { return origin_server_.get(); }
+  EmbeddedTestServer* destination_server() const {
+    return destination_server_.get();
+  }
 
  private:
   std::unique_ptr<EmbeddedTestServer> origin_server_;
@@ -8903,6 +8907,88 @@
   VerifyReferrerAfterRedirect(URLRequest::NO_REFERRER, GURL(), GURL());
 }
 
+TEST_F(URLRequestTestReferrerPolicy,
+       HTTPSToHTTPSSameOriginRequestCrossOrginReferrer) {
+  InstantiateSameOriginServers(net::EmbeddedTestServer::TYPE_HTTPS);
+  // The request is same-origin, however its referrer is cross-origin.
+  GURL referrer("https://foo.test/some/path.html");
+
+  VerifyReferrerAfterRedirect(
+      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+      referrer, referrer);
+
+  VerifyReferrerAfterRedirect(
+      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+      referrer, referrer);
+
+  VerifyReferrerAfterRedirect(
+      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, referrer, referrer);
+
+  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, referrer,
+                              referrer);
+
+  // The original referrer set on the request is expected to obey the referrer
+  // policy and already be stripped to the origin; thus this test case just
+  // checks that this policy doesn't cause the referrer to change when following
+  // a redirect.
+  VerifyReferrerAfterRedirect(URLRequest::ORIGIN, referrer.GetOrigin(),
+                              referrer.GetOrigin());
+
+  VerifyReferrerAfterRedirect(
+      URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN, referrer,
+      referrer);
+
+  // The original referrer set on the request is expected to obey the referrer
+  // policy and already be stripped to the origin, though it should be
+  // subsequently cleared during the downgrading redirect.
+  VerifyReferrerAfterRedirect(
+      URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+      referrer.GetOrigin(), referrer.GetOrigin());
+  VerifyReferrerAfterRedirect(URLRequest::NO_REFERRER, GURL(), GURL());
+}
+
+TEST_F(URLRequestTestReferrerPolicy,
+       HTTPSToHTTPSCrossOriginRequestCrossOrginReferrer) {
+  InstantiateCrossOriginServers(net::EmbeddedTestServer::TYPE_HTTPS,
+                                net::EmbeddedTestServer::TYPE_HTTPS);
+  // The request is cross-origin, and so is its referrer.
+  GURL referrer = destination_server()->GetURL("/path/to/file.html");
+
+  VerifyReferrerAfterRedirect(
+      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+      referrer, referrer);
+
+  VerifyReferrerAfterRedirect(
+      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+      referrer, referrer.GetOrigin());
+
+  VerifyReferrerAfterRedirect(
+      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, referrer,
+      referrer.GetOrigin());
+
+  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, referrer,
+                              referrer);
+
+  // The original referrer set on the request is expected to obey the referrer
+  // policy and already be stripped to the origin; thus this test case just
+  // checks that this policy doesn't cause the referrer to change when following
+  // a redirect.
+  VerifyReferrerAfterRedirect(URLRequest::ORIGIN, referrer.GetOrigin(),
+                              referrer.GetOrigin());
+
+  VerifyReferrerAfterRedirect(
+      URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN, referrer, GURL());
+
+  // The original referrer set on the request is expected to obey the referrer
+  // policy and already be stripped to the origin, though it should be
+  // subsequently cleared during the downgrading redirect.
+  VerifyReferrerAfterRedirect(
+      URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+      referrer.GetOrigin(), referrer.GetOrigin());
+
+  VerifyReferrerAfterRedirect(URLRequest::NO_REFERRER, GURL(), GURL());
+}
+
 class HTTPSRequestTest : public TestWithTaskEnvironment {
  public:
   HTTPSRequestTest() : default_context_(true) {
diff --git a/services/data_decoder/data_decoder_service.cc b/services/data_decoder/data_decoder_service.cc
index 8647bb2..bcfbb394 100644
--- a/services/data_decoder/data_decoder_service.cc
+++ b/services/data_decoder/data_decoder_service.cc
@@ -84,10 +84,11 @@
       std::move(receiver));
 }
 
-void DataDecoderService::BindJsonParser(mojom::JsonParserRequest request) {
-  mojo::MakeStrongBinding(
+void DataDecoderService::BindJsonParser(
+    mojo::PendingReceiver<mojom::JsonParser> receiver) {
+  mojo::MakeSelfOwnedReceiver(
       std::make_unique<JsonParserImpl>(keepalive_.CreateRef()),
-      std::move(request));
+      std::move(receiver));
 }
 
 void DataDecoderService::BindXmlParser(mojom::XmlParserRequest request) {
diff --git a/services/data_decoder/data_decoder_service.h b/services/data_decoder/data_decoder_service.h
index ff35c7b..4aa4bda 100644
--- a/services/data_decoder/data_decoder_service.h
+++ b/services/data_decoder/data_decoder_service.h
@@ -44,7 +44,7 @@
   void BindBundledExchangesParserFactory(
       mojom::BundledExchangesParserFactoryRequest request);
   void BindImageDecoder(mojo::PendingReceiver<mojom::ImageDecoder> receiver);
-  void BindJsonParser(mojom::JsonParserRequest request);
+  void BindJsonParser(mojo::PendingReceiver<mojom::JsonParser> receiver);
   void BindXmlParser(mojom::XmlParserRequest request);
 
 #ifdef OS_CHROMEOS
diff --git a/services/data_decoder/public/cpp/safe_json_parser_impl.cc b/services/data_decoder/public/cpp/safe_json_parser_impl.cc
index 382ea647..f2c5eb68 100644
--- a/services/data_decoder/public/cpp/safe_json_parser_impl.cc
+++ b/services/data_decoder/public/cpp/safe_json_parser_impl.cc
@@ -27,10 +27,10 @@
       error_callback_(std::move(error_callback)) {
   // If no batch ID has been provided, use a random instance ID to guarantee the
   // connection is to a new service running in its own process.
-  connector->BindInterface(
+  connector->Connect(
       service_manager::ServiceFilter::ByNameWithId(
           mojom::kServiceName, batch_id.value_or(base::Token::CreateRandom())),
-      &json_parser_ptr_);
+      json_parser_.BindNewPipeAndPassReceiver());
 }
 
 SafeJsonParserImpl::~SafeJsonParserImpl() = default;
@@ -38,9 +38,9 @@
 void SafeJsonParserImpl::Start() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  json_parser_ptr_.set_connection_error_handler(base::Bind(
+  json_parser_.set_disconnect_handler(base::Bind(
       &SafeJsonParserImpl::OnConnectionError, base::Unretained(this)));
-  json_parser_ptr_->Parse(
+  json_parser_->Parse(
       std::move(unsafe_json_),
       base::Bind(&SafeJsonParserImpl::OnParseDone, base::Unretained(this)));
 }
@@ -49,7 +49,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // Shut down the utility process.
-  json_parser_ptr_.reset();
+  json_parser_.reset();
 
   ReportResults(base::nullopt,
                 "Connection error with the json parser process.");
@@ -60,7 +60,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // Shut down the utility process.
-  json_parser_ptr_.reset();
+  json_parser_.reset();
 
   ReportResults(std::move(result), error.value_or(""));
 }
diff --git a/services/data_decoder/public/cpp/safe_json_parser_impl.h b/services/data_decoder/public/cpp/safe_json_parser_impl.h
index eb04331..a43fbf9 100644
--- a/services/data_decoder/public/cpp/safe_json_parser_impl.h
+++ b/services/data_decoder/public/cpp/safe_json_parser_impl.h
@@ -15,6 +15,7 @@
 #include "base/threading/thread_checker.h"
 #include "base/token.h"
 #include "base/values.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/data_decoder/public/cpp/safe_json_parser.h"
 #include "services/data_decoder/public/mojom/json_parser.mojom.h"
 
@@ -54,7 +55,7 @@
   SuccessCallback success_callback_;
   ErrorCallback error_callback_;
 
-  mojom::JsonParserPtr json_parser_ptr_;
+  mojo::Remote<mojom::JsonParser> json_parser_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/services/data_decoder/public/cpp/test_data_decoder_service.cc b/services/data_decoder/public/cpp/test_data_decoder_service.cc
index a71ff92..dd573ce96 100644
--- a/services/data_decoder/public/cpp/test_data_decoder_service.cc
+++ b/services/data_decoder/public/cpp/test_data_decoder_service.cc
@@ -38,9 +38,10 @@
   DCHECK(interface_name == mojom::JsonParser::Name_ ||
          interface_name == mojom::ImageDecoder::Name_);
   if (interface_name == mojom::JsonParser::Name_ && crash_json_) {
-    DCHECK(!json_parser_binding_);
-    json_parser_binding_ = std::make_unique<mojo::Binding<mojom::JsonParser>>(
-        this, mojom::JsonParserRequest(std::move(interface_pipe)));
+    DCHECK(!json_parser_receiver_);
+    json_parser_receiver_ = std::make_unique<mojo::Receiver<mojom::JsonParser>>(
+        this,
+        mojo::PendingReceiver<mojom::JsonParser>(std::move(interface_pipe)));
     return;
   }
   if (interface_name == mojom::ImageDecoder::Name_ && crash_image_) {
@@ -76,7 +77,7 @@
 
 void CrashyDataDecoderService::Parse(const std::string& json,
                                      ParseCallback callback) {
-  json_parser_binding_.reset();
+  json_parser_receiver_.reset();
 }
 
 }  // namespace data_decoder
diff --git a/services/data_decoder/public/cpp/test_data_decoder_service.h b/services/data_decoder/public/cpp/test_data_decoder_service.h
index ae252ae..ab99a4a 100644
--- a/services/data_decoder/public/cpp/test_data_decoder_service.h
+++ b/services/data_decoder/public/cpp/test_data_decoder_service.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "services/data_decoder/data_decoder_service.h"
 #include "services/data_decoder/public/mojom/image_decoder.mojom.h"
@@ -80,7 +79,7 @@
   service_manager::ServiceBinding binding_;
 
   std::unique_ptr<mojo::Receiver<mojom::ImageDecoder>> image_decoder_receiver_;
-  std::unique_ptr<mojo::Binding<mojom::JsonParser>> json_parser_binding_;
+  std::unique_ptr<mojo::Receiver<mojom::JsonParser>> json_parser_receiver_;
 
   // An instance of the actual DataDecoderService we forward requests to for
   // interfaces that should not crash.
diff --git a/services/image_annotation/annotator.cc b/services/image_annotation/annotator.cc
index a387062..863c318f 100644
--- a/services/image_annotation/annotator.cc
+++ b/services/image_annotation/annotator.cc
@@ -642,9 +642,9 @@
   ReportServerResponseSizeBytes(json_response->size());
 
   // Send JSON string to a dedicated service for safe parsing.
-  GetJsonParser().Parse(*json_response,
-                        base::BindOnce(&Annotator::OnResponseJsonParsed,
-                                       base::Unretained(this), request_keys));
+  GetJsonParser()->Parse(*json_response,
+                         base::BindOnce(&Annotator::OnResponseJsonParsed,
+                                        base::Unretained(this), request_keys));
 }
 
 void Annotator::OnResponseJsonParsed(
@@ -708,16 +708,16 @@
   }
 }
 
-data_decoder::mojom::JsonParser& Annotator::GetJsonParser() {
+data_decoder::mojom::JsonParser* Annotator::GetJsonParser() {
   if (!json_parser_) {
-    connector_->BindInterface(data_decoder::mojom::kServiceName,
-                              mojo::MakeRequest(&json_parser_));
-    json_parser_.set_connection_error_handler(base::BindOnce(
+    connector_->Connect(data_decoder::mojom::kServiceName,
+                        json_parser_.BindNewPipeAndPassReceiver());
+    json_parser_.set_disconnect_handler(base::BindOnce(
         [](Annotator* const annotator) { annotator->json_parser_.reset(); },
         base::Unretained(this)));
   }
 
-  return *json_parser_;
+  return json_parser_.get();
 }
 
 void Annotator::RemoveRequestInfo(
diff --git a/services/image_annotation/annotator.h b/services/image_annotation/annotator.h
index 834d9bb..08863ba 100644
--- a/services/image_annotation/annotator.h
+++ b/services/image_annotation/annotator.h
@@ -18,6 +18,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/data_decoder/public/mojom/json_parser.mojom.h"
 #include "services/image_annotation/public/mojom/image_annotation.mojom.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -153,7 +154,7 @@
 
   // Create or reuse a connection to the data decoder service for safe JSON
   // parsing.
-  data_decoder::mojom::JsonParser& GetJsonParser();
+  data_decoder::mojom::JsonParser* GetJsonParser();
 
   // Removes the given request, reassigning local processing if its associated
   // image processor had some ongoing.
@@ -232,7 +233,7 @@
   mojo::BindingSet<mojom::Annotator> bindings_;
 
   // Should not be used directly; GetJsonParser() should be called instead.
-  data_decoder::mojom::JsonParserPtr json_parser_;
+  mojo::Remote<data_decoder::mojom::JsonParser> json_parser_;
 
   // A timer used to throttle server request frequency.
   base::RepeatingTimer server_request_timer_;
diff --git a/services/network/cors/cors_url_loader_factory_unittest.cc b/services/network/cors/cors_url_loader_factory_unittest.cc
index 3488e22..6de7dd2 100644
--- a/services/network/cors/cors_url_loader_factory_unittest.cc
+++ b/services/network/cors/cors_url_loader_factory_unittest.cc
@@ -39,8 +39,7 @@
 class CorsURLLoaderFactoryTest : public testing::Test {
  public:
   CorsURLLoaderFactoryTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
-        resource_scheduler_(true) {
+      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
     net::URLRequestContextBuilder context_builder;
     context_builder.set_proxy_resolution_service(
         net::ProxyResolutionService::CreateDirect());
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc
index 80afcfc..ecf4547 100644
--- a/services/network/cors/cors_url_loader_unittest.cc
+++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -143,8 +143,7 @@
   using ReferrerPolicy = net::URLRequest::ReferrerPolicy;
 
   CorsURLLoaderTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
-        resource_scheduler_(true) {
+      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
     net::URLRequestContextBuilder context_builder;
     context_builder.set_proxy_resolution_service(
         net::ProxyResolutionService::CreateDirect());
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 3a0e058..7efab34 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -320,7 +320,6 @@
 }  // namespace
 
 constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
-constexpr bool NetworkContext::enable_resource_scheduler_;
 
 NetworkContext::PendingCertVerify::PendingCertVerify() = default;
 NetworkContext::PendingCertVerify::~PendingCertVerify() = default;
@@ -538,8 +537,7 @@
 
   socket_factory_ = std::make_unique<SocketFactory>(
       url_request_context_->net_log(), url_request_context_);
-  resource_scheduler_ =
-      std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
+  resource_scheduler_ = std::make_unique<ResourceScheduler>();
 
   origin_policy_manager_ = std::make_unique<OriginPolicyManager>(this);
 
@@ -568,8 +566,7 @@
   // May be nullptr in tests.
   if (network_service_)
     network_service_->RegisterNetworkContext(this);
-  resource_scheduler_ =
-      std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
+  resource_scheduler_ = std::make_unique<ResourceScheduler>();
 
   for (const auto& key : cors_exempt_header_list)
     cors_exempt_header_list_.insert(key);
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 608553f..93a6e9d 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -101,8 +101,8 @@
 //
 // When the network service is enabled, NetworkContexts are created through
 // NetworkService's mojo interface and are owned jointly by the NetworkService
-// and the NetworkContextPtr used to talk to them, and the NetworkContext is
-// destroyed when either one is torn down.
+// and the mojo::Remote<NetworkContext> used to talk to them, and the
+// NetworkContext is destroyed when either one is torn down.
 class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
     : public mojom::NetworkContext {
  public:
@@ -536,9 +536,6 @@
   // Owned by the URLRequestContext
   net::StaticHttpUserAgentSettings* user_agent_settings_ = nullptr;
 
-  // TODO(yhirano): Consult with switches::kDisableResourceScheduler.
-  constexpr static bool enable_resource_scheduler_ = true;
-
   // Pointed to by the TransportSecurityState (owned by the
   // URLRequestContext), and must be disconnected from it before it's destroyed.
   std::unique_ptr<net::ReportSender> certificate_report_sender_;
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
index dd439e2..de48b10 100644
--- a/services/network/network_context_unittest.cc
+++ b/services/network/network_context_unittest.cc
@@ -353,8 +353,10 @@
 
   std::unique_ptr<NetworkContext> CreateContextWithParams(
       mojom::NetworkContextParamsPtr context_params) {
+    network_context_remote_.reset();
     return std::make_unique<NetworkContext>(
-        network_service_.get(), mojo::MakeRequest(&network_context_ptr_),
+        network_service_.get(),
+        network_context_remote_.BindNewPipeAndPassReceiver(),
         std::move(context_params));
   }
 
@@ -441,9 +443,10 @@
   base::test::TaskEnvironment task_environment_;
   std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
   std::unique_ptr<NetworkService> network_service_;
-  // Stores the NetworkContextPtr of the most recently created NetworkContext.
-  // Not strictly needed, but seems best to mimic real-world usage.
-  mojom::NetworkContextPtr network_context_ptr_;
+  // Stores the mojo::Remote<NetworkContext> of the most recently created
+  // NetworkContext. Not strictly needed, but seems best to mimic real-world
+  // usage.
+  mojo::Remote<mojom::NetworkContext> network_context_remote_;
 };
 
 TEST_F(NetworkContextTest, DestroyContextWithLiveRequest) {
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index bc748d2..8b93500 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -552,7 +552,7 @@
   ContinueWithCertificate(network.mojom.X509Certificate x509_certificate,
                           string provider_name,
                           array<uint16> algorithm_preferences,
-                          SSLPrivateKey ssl_private_key);
+                          pending_remote<SSLPrivateKey> ssl_private_key);
 
   // Affirmatively select no certificate (this is cached and can affect future
   // URLRequests). Does not cancel the URLRequest.
diff --git a/services/network/resource_scheduler/resource_scheduler.cc b/services/network/resource_scheduler/resource_scheduler.cc
index b2448737..dc6e9db 100644
--- a/services/network/resource_scheduler/resource_scheduler.cc
+++ b/services/network/resource_scheduler/resource_scheduler.cc
@@ -1026,9 +1026,6 @@
 
   ShouldStartReqResult ShouldStartRequest(
       ScheduledResourceRequestImpl* request) const {
-    if (!resource_scheduler_->enabled())
-      return START_REQUEST;
-
     // Browser requests are treated differently since they are not user-facing.
     if (is_browser_client_) {
       if (ShouldThrottleBrowserInitiatedRequestDueToP2PConnections(*request)) {
@@ -1333,11 +1330,9 @@
   base::WeakPtrFactory<ResourceScheduler::Client> weak_ptr_factory_{this};
 };
 
-ResourceScheduler::ResourceScheduler(bool enabled,
-                                     const base::TickClock* tick_clock)
+ResourceScheduler::ResourceScheduler(const base::TickClock* tick_clock)
     : tick_clock_(tick_clock ? tick_clock
                              : base::DefaultTickClock::GetInstance()),
-      enabled_(enabled),
       queued_requests_dispatch_periodicity_(
           GetQueuedRequestsDispatchPeriodicity()),
       task_runner_(base::ThreadTaskRunnerHandle::Get()) {
diff --git a/services/network/resource_scheduler/resource_scheduler.h b/services/network/resource_scheduler/resource_scheduler.h
index df92a6d..95503d2c 100644
--- a/services/network/resource_scheduler/resource_scheduler.h
+++ b/services/network/resource_scheduler/resource_scheduler.h
@@ -83,8 +83,7 @@
     base::OnceClosure resume_callback_;
   };
 
-  explicit ResourceScheduler(bool enabled,
-                             const base::TickClock* tick_clock = nullptr);
+  explicit ResourceScheduler(const base::TickClock* tick_clock = nullptr);
   ~ResourceScheduler();
 
   // Requests that this ResourceScheduler schedule, and eventually loads, the
@@ -141,8 +140,6 @@
     task_runner_ = std::move(sequenced_task_runner);
   }
 
-  bool enabled() const { return enabled_; }
-
   void SetResourceSchedulerParamsManagerForTests(
       const ResourceSchedulerParamsManager& resource_scheduler_params_manager);
 
@@ -188,11 +185,6 @@
   // Timer to dispatch requests that may have been queued for too long.
   base::OneShotTimer long_queued_requests_dispatch_timer_;
 
-  // Whether or not to enable ResourceScheduling. This will almost always be
-  // enabled, except for some C++ headless embedders who may implement their own
-  // resource scheduling via protocol handlers.
-  const bool enabled_;
-
   // Duration after which the timer to dispatch queued requests should fire.
   const base::TimeDelta queued_requests_dispatch_periodicity_;
 
diff --git a/services/network/resource_scheduler/resource_scheduler_unittest.cc b/services/network/resource_scheduler/resource_scheduler_unittest.cc
index ce7451e..22a6d9e 100644
--- a/services/network/resource_scheduler/resource_scheduler_unittest.cc
+++ b/services/network/resource_scheduler/resource_scheduler_unittest.cc
@@ -179,11 +179,11 @@
 
   // Done separately from construction to allow for modification of command
   // line flags in tests.
-  void InitializeScheduler(bool enabled = true) {
+  void InitializeScheduler() {
     CleanupScheduler();
 
     // Destroys previous scheduler.
-    scheduler_.reset(new ResourceScheduler(enabled, &tick_clock_));
+    scheduler_ = std::make_unique<ResourceScheduler>(&tick_clock_);
 
     scheduler()->SetResourceSchedulerParamsManagerForTests(
         resource_scheduler_params_manager_);
@@ -1657,7 +1657,7 @@
       1);
 }
 
-TEST_F(ResourceSchedulerTest, SchedulerEnabled) {
+TEST_F(ResourceSchedulerTest, Simple) {
   SetMaxDelayableRequests(1);
   std::unique_ptr<TestRequest> high(
       NewRequest("http://host/high", net::HIGHEST));
@@ -1669,26 +1669,12 @@
   EXPECT_FALSE(request->started());
 }
 
-TEST_F(ResourceSchedulerTest, SchedulerDisabled) {
-  InitializeScheduler(false);
-
-  std::unique_ptr<TestRequest> high(
-      NewRequest("http://host/high", net::HIGHEST));
-  std::unique_ptr<TestRequest> low(NewRequest("http://host/req", net::LOWEST));
-
-  std::unique_ptr<TestRequest> request(
-      NewRequest("http://host/req", net::LOWEST));
-
-  // Normally |request| wouldn't start immediately due to the |high| priority
-  // request, but when the scheduler is disabled it starts immediately.
-  EXPECT_TRUE(request->started());
-}
-
 TEST_F(ResourceSchedulerTest, MultipleInstances_1) {
   SetMaxDelayableRequests(1);
   // In some circumstances there may exist multiple instances.
-  ResourceScheduler another_scheduler(false,
-                                      base::DefaultTickClock::GetInstance());
+  ResourceScheduler another_scheduler(base::DefaultTickClock::GetInstance());
+  another_scheduler.SetResourceSchedulerParamsManagerForTests(
+      ResourceSchedulerParamsManager(FixedParamsManager(99)));
 
   std::unique_ptr<TestRequest> high(
       NewRequest("http://host/high", net::HIGHEST));
@@ -1697,15 +1683,13 @@
   std::unique_ptr<TestRequest> request(
       NewRequest("http://host/req", net::LOWEST));
 
-  // Though |another_scheduler| is disabled, this request should be throttled
-  // as it's handled by |scheduler_| which is active.
+  // This request should be throttled as it's handled by |scheduler_|.
   EXPECT_FALSE(request->started());
 }
 
 TEST_F(ResourceSchedulerTest, MultipleInstances_2) {
   SetMaxDelayableRequests(1);
-  ResourceScheduler another_scheduler(true,
-                                      base::DefaultTickClock::GetInstance());
+  ResourceScheduler another_scheduler(base::DefaultTickClock::GetInstance());
   another_scheduler.OnClientCreated(kChildId, kRouteId,
                                     &network_quality_estimator_);
 
diff --git a/services/network/test/test_shared_url_loader_factory.cc b/services/network/test/test_shared_url_loader_factory.cc
index a6ab2c2..4fd1cd0 100644
--- a/services/network/test/test_shared_url_loader_factory.cc
+++ b/services/network/test/test_shared_url_loader_factory.cc
@@ -14,9 +14,9 @@
 TestSharedURLLoaderFactory::TestSharedURLLoaderFactory(
     NetworkService* network_service) {
   url_request_context_ = std::make_unique<net::TestURLRequestContext>();
-  mojom::NetworkContextPtr network_context;
+  mojo::Remote<mojom::NetworkContext> network_context;
   network_context_ = std::make_unique<NetworkContext>(
-      network_service, mojo::MakeRequest(&network_context),
+      network_service, network_context.BindNewPipeAndPassReceiver(),
       url_request_context_.get(),
       /*cors_exempt_header_list=*/std::vector<std::string>());
   mojom::URLLoaderFactoryParamsPtr params =
diff --git a/services/network/transitional_url_loader_factory_owner.cc b/services/network/transitional_url_loader_factory_owner.cc
index 1791187..730ce820 100644
--- a/services/network/transitional_url_loader_factory_owner.cc
+++ b/services/network/transitional_url_loader_factory_owner.cc
@@ -92,12 +92,13 @@
   DCHECK(!disallowed_in_process().IsSet());
 
   if (!shared_url_loader_factory_) {
-    core_->CreateNetworkContext(mojo::MakeRequest(&network_context_pipe_));
+    core_->CreateNetworkContext(
+        network_context_remote_.BindNewPipeAndPassReceiver());
     auto url_loader_factory_params =
         network::mojom::URLLoaderFactoryParams::New();
     url_loader_factory_params->process_id = mojom::kBrowserProcessId;
     url_loader_factory_params->is_corb_enabled = false;
-    network_context_pipe_->CreateURLLoaderFactory(
+    network_context_remote_->CreateURLLoaderFactory(
         mojo::MakeRequest(&url_loader_factory_),
         std::move(url_loader_factory_params));
     shared_url_loader_factory_ =
@@ -111,7 +112,7 @@
 network::mojom::NetworkContext*
 TransitionalURLLoaderFactoryOwner::GetNetworkContext() {
   GetURLLoaderFactory();
-  return network_context_pipe_.get();
+  return network_context_remote_.get();
 }
 
 void TransitionalURLLoaderFactoryOwner::DisallowUsageInProcess() {
diff --git a/services/network/transitional_url_loader_factory_owner.h b/services/network/transitional_url_loader_factory_owner.h
index 3105b250..ed7631e 100644
--- a/services/network/transitional_url_loader_factory_owner.h
+++ b/services/network/transitional_url_loader_factory_owner.h
@@ -13,6 +13,7 @@
 #include "base/sequence_checker.h"
 #include "base/sequenced_task_runner.h"
 #include "base/synchronization/atomic_flag.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
@@ -54,7 +55,7 @@
   static base::AtomicFlag& disallowed_in_process();
 
   std::unique_ptr<Core> core_;  // deleted cross-thread
-  network::mojom::NetworkContextPtr network_context_pipe_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
   network::mojom::URLLoaderFactoryPtr url_loader_factory_;
   scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
       shared_url_loader_factory_;
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 341e1c7..69dbf99 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -252,13 +252,14 @@
 
 class SSLPrivateKeyInternal : public net::SSLPrivateKey {
  public:
-  SSLPrivateKeyInternal(const std::string& provider_name,
-                        const std::vector<uint16_t>& algorithm_preferences,
-                        mojom::SSLPrivateKeyPtr ssl_private_key)
+  SSLPrivateKeyInternal(
+      const std::string& provider_name,
+      const std::vector<uint16_t>& algorithm_preferences,
+      mojo::PendingRemote<mojom::SSLPrivateKey> ssl_private_key)
       : provider_name_(provider_name),
         algorithm_preferences_(algorithm_preferences),
         ssl_private_key_(std::move(ssl_private_key)) {
-    ssl_private_key_.set_connection_error_handler(
+    ssl_private_key_.set_disconnect_handler(
         base::BindOnce(&SSLPrivateKeyInternal::HandleSSLPrivateKeyError,
                        base::Unretained(this)));
   }
@@ -274,7 +275,7 @@
             base::span<const uint8_t> input,
             net::SSLPrivateKey::SignCallback callback) override {
     std::vector<uint8_t> input_vector(input.begin(), input.end());
-    if (!ssl_private_key_ || ssl_private_key_.encountered_error()) {
+    if (!ssl_private_key_ || !ssl_private_key_.is_connected()) {
       base::ThreadTaskRunnerHandle::Get()->PostTask(
           FROM_HERE,
           base::BindOnce(std::move(callback),
@@ -303,7 +304,7 @@
 
   std::string provider_name_;
   std::vector<uint16_t> algorithm_preferences_;
-  mojom::SSLPrivateKeyPtr ssl_private_key_;
+  mojo::Remote<mojom::SSLPrivateKey> ssl_private_key_;
 
   DISALLOW_COPY_AND_ASSIGN(SSLPrivateKeyInternal);
 };
@@ -1275,7 +1276,7 @@
     const scoped_refptr<net::X509Certificate>& x509_certificate,
     const std::string& provider_name,
     const std::vector<uint16_t>& algorithm_preferences,
-    mojom::SSLPrivateKeyPtr ssl_private_key) {
+    mojo::PendingRemote<mojom::SSLPrivateKey> ssl_private_key) {
   client_cert_responder_receiver_.reset();
   auto key = base::MakeRefCounted<SSLPrivateKeyInternal>(
       provider_name, algorithm_preferences, std::move(ssl_private_key));
diff --git a/services/network/url_loader.h b/services/network/url_loader.h
index 302e469ad..1d72901 100644
--- a/services/network/url_loader.h
+++ b/services/network/url_loader.h
@@ -130,7 +130,7 @@
       const scoped_refptr<net::X509Certificate>& x509_certificate,
       const std::string& provider_name,
       const std::vector<uint16_t>& algorithm_preferences,
-      mojom::SSLPrivateKeyPtr ssl_private_key) override;
+      mojo::PendingRemote<mojom::SSLPrivateKey> ssl_private_key) override;
   void ContinueWithoutCertificate() override;
   void CancelRequest() override;
 
@@ -342,8 +342,6 @@
 
   scoped_refptr<ResourceSchedulerClient> resource_scheduler_client_;
 
-  mojom::SSLPrivateKeyPtr ssl_private_key_;
-
   base::WeakPtr<KeepaliveStatisticsRecorder> keepalive_statistics_recorder_;
 
   base::WeakPtr<NetworkUsageAccumulator> network_usage_accumulator_;
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index 3d397d8c..bf3cd5b 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -33,7 +33,7 @@
 #include "build/build_config.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "mojo/public/cpp/system/data_pipe_utils.h"
 #include "mojo/public/cpp/system/wait.h"
 #include "net/base/escape.h"
@@ -385,8 +385,7 @@
 class URLLoaderTest : public testing::Test {
  public:
   URLLoaderTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
-        resource_scheduler_(true) {
+      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
     net::TestRootCerts* root_certs = net::TestRootCerts::GetInstance();
     root_certs->AddFromFile(
         net::GetTestCertsDirectory().AppendASCII("quic-root.pem"));
@@ -2642,7 +2641,7 @@
       case CertificateResponse::INVALID_CERTIFICATE_SIGNATURE:
         client_cert_responder->ContinueWithCertificate(
             std::move(certificate_), provider_name_, algorithm_preferences_,
-            std::move(ssl_private_key_ptr_));
+            std::move(ssl_private_key_remote_));
         break;
       case CertificateResponse::DESTROY_CLIENT_CERT_RESPONDER:
         // Send no response and let the local variable be destroyed.
@@ -2727,10 +2726,9 @@
     ssl_private_key_ = std::move(ssl_private_key);
     provider_name_ = ssl_private_key_->GetProviderName();
     algorithm_preferences_ = ssl_private_key_->GetAlgorithmPreferences();
-    auto ssl_private_key_request = mojo::MakeRequest(&ssl_private_key_ptr_);
-    mojo::MakeStrongBinding(
+    mojo::MakeSelfOwnedReceiver(
         std::make_unique<FakeSSLPrivateKeyImpl>(std::move(ssl_private_key_)),
-        std::move(ssl_private_key_request));
+        ssl_private_key_remote_.InitWithNewPipeAndPassReceiver());
   }
 
   void set_certificate(scoped_refptr<net::X509Certificate> certificate) {
@@ -2762,7 +2760,7 @@
   CertificateResponse certificate_response_ = CertificateResponse::INVALID;
   scoped_refptr<net::SSLPrivateKey> ssl_private_key_;
   scoped_refptr<net::X509Certificate> certificate_;
-  network::mojom::SSLPrivateKeyPtr ssl_private_key_ptr_;
+  mojo::PendingRemote<network::mojom::SSLPrivateKey> ssl_private_key_remote_;
   std::string provider_name_;
   std::vector<uint16_t> algorithm_preferences_;
   int on_certificate_requested_counter_ = 0;
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
index 418af38..fea9f790 100644
--- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
+++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
@@ -95,14 +95,14 @@
 
 service_manager::Identity CoordinatorImpl::GetClientIdentityForCurrentRequest()
     const {
-  return bindings_.dispatch_context();
+  return receivers_.current_context();
 }
 
-void CoordinatorImpl::BindCoordinatorRequest(
-    mojom::CoordinatorRequest request,
+void CoordinatorImpl::BindCoordinatorReceiver(
+    mojo::PendingReceiver<mojom::Coordinator> receiver,
     const service_manager::BindSourceInfo& source_info) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  bindings_.AddBinding(this, std::move(request), source_info.identity);
+  receivers_.Add(this, std::move(receiver), source_info.identity);
 }
 
 void CoordinatorImpl::BindHeapProfilerHelperRequest(
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.h b/services/resource_coordinator/memory_instrumentation/coordinator_impl.h
index cefc0c4..4b017e4 100644
--- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.h
+++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.h
@@ -16,6 +16,7 @@
 #include "base/trace_event/memory_dump_request_args.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/resource_coordinator/memory_instrumentation/process_map.h"
 #include "services/resource_coordinator/memory_instrumentation/queued_request.h"
 #include "services/resource_coordinator/public/cpp/memory_instrumentation/coordinator.h"
@@ -46,8 +47,8 @@
   CoordinatorImpl(service_manager::Connector* connector);
 
   // Binds a client library to this coordinator instance.
-  void BindCoordinatorRequest(
-      mojom::CoordinatorRequest,
+  void BindCoordinatorReceiver(
+      mojo::PendingReceiver<mojom::Coordinator>,
       const service_manager::BindSourceInfo& source_info) override;
 
   void BindHeapProfilerHelperRequest(
@@ -182,8 +183,8 @@
       in_progress_vm_region_requests_;
 
   // There may be extant callbacks in |queued_memory_dump_requests_|. The
-  // bindings_ must be closed before destroying the un-run callbacks.
-  mojo::BindingSet<mojom::Coordinator, service_manager::Identity> bindings_;
+  // receivers_ must be closed before destroying the un-run callbacks.
+  mojo::ReceiverSet<mojom::Coordinator, service_manager::Identity> receivers_;
 
   // There may be extant callbacks in |queued_memory_dump_requests_|. The
   // bindings_ must be closed before destroying the un-run callbacks.
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
index c5f16c55..440ae0b 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
@@ -48,7 +48,7 @@
     MemoryInstrumentation::CreateInstance(config.connector,
                                           config.service_name);
   } else {
-    config.coordinator_for_testing->BindCoordinatorRequest(
+    config.coordinator_for_testing->BindCoordinatorReceiver(
         mojo::MakeRequest(&coordinator_), service_manager::BindSourceInfo());
   }
 
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/coordinator.h b/services/resource_coordinator/public/cpp/memory_instrumentation/coordinator.h
index dad877d..f27d245 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/coordinator.h
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/coordinator.h
@@ -15,9 +15,9 @@
 
 class Coordinator {
  public:
-  // Binds a CoordinatorRequest to this Coordinator instance.
-  virtual void BindCoordinatorRequest(
-      mojom::CoordinatorRequest,
+  // Binds a Coordinator Receiver to this Coordinator instance.
+  virtual void BindCoordinatorReceiver(
+      mojo::PendingReceiver<mojom::Coordinator>,
       const service_manager::BindSourceInfo& source_info) = 0;
 };
 
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_integration_unittest.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_integration_unittest.cc
index 7ad5c17..20ab87c 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_integration_unittest.cc
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_integration_unittest.cc
@@ -21,7 +21,7 @@
 #include "base/trace_event/trace_config.h"
 #include "base/trace_event/trace_config_memory_test_util.h"
 #include "base/trace_event/trace_log.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/resource_coordinator/public/cpp/memory_instrumentation/coordinator.h"
 #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -101,10 +101,10 @@
  public:
   MockCoordinator(MemoryTracingIntegrationTest* client) : client_(client) {}
 
-  void BindCoordinatorRequest(
-      mojom::CoordinatorRequest request,
+  void BindCoordinatorReceiver(
+      mojo::PendingReceiver<mojom::Coordinator> receiver,
       const service_manager::BindSourceInfo& source_info) override {
-    bindings_.AddBinding(this, std::move(request));
+    receivers_.Add(this, std::move(receiver));
   }
 
   void RegisterClientProcess(mojom::ClientProcessPtr,
@@ -133,7 +133,7 @@
       RequestGlobalMemoryDumpAndAppendToTraceCallback) override;
 
  private:
-  mojo::BindingSet<mojom::Coordinator> bindings_;
+  mojo::ReceiverSet<mojom::Coordinator> receivers_;
   MemoryTracingIntegrationTest* client_;
 };
 
diff --git a/services/resource_coordinator/resource_coordinator_service.cc b/services/resource_coordinator/resource_coordinator_service.cc
index 54599f1..65c456e6 100644
--- a/services/resource_coordinator/resource_coordinator_service.cc
+++ b/services/resource_coordinator/resource_coordinator_service.cc
@@ -31,7 +31,7 @@
       std::make_unique<memory_instrumentation::CoordinatorImpl>(
           service_binding_.GetConnector());
   registry_.AddInterface(base::BindRepeating(
-      &memory_instrumentation::CoordinatorImpl::BindCoordinatorRequest,
+      &memory_instrumentation::CoordinatorImpl::BindCoordinatorReceiver,
       base::Unretained(memory_instrumentation_coordinator_.get())));
   registry_.AddInterface(base::BindRepeating(
       &memory_instrumentation::CoordinatorImpl::BindHeapProfilerHelperRequest,
diff --git a/services/shape_detection/barcode_detection_provider_impl.cc b/services/shape_detection/barcode_detection_provider_impl.cc
index 518f7f5d..b5edc1a8 100644
--- a/services/shape_detection/barcode_detection_provider_impl.cc
+++ b/services/shape_detection/barcode_detection_provider_impl.cc
@@ -9,7 +9,7 @@
 namespace shape_detection {
 
 void BarcodeDetectionProviderImpl::CreateBarcodeDetection(
-    shape_detection::mojom::BarcodeDetectionRequest request,
+    mojo::PendingReceiver<shape_detection::mojom::BarcodeDetection> receiver,
     shape_detection::mojom::BarcodeDetectorOptionsPtr options) {
   DLOG(ERROR) << "Platform not supported for Barcode Detection Service.";
 }
diff --git a/services/shape_detection/barcode_detection_provider_impl.h b/services/shape_detection/barcode_detection_provider_impl.h
index 1a16b87..cff6f22 100644
--- a/services/shape_detection/barcode_detection_provider_impl.h
+++ b/services/shape_detection/barcode_detection_provider_impl.h
@@ -25,7 +25,7 @@
   }
 
   void CreateBarcodeDetection(
-      shape_detection::mojom::BarcodeDetectionRequest request,
+      mojo::PendingReceiver<shape_detection::mojom::BarcodeDetection> receiver,
       shape_detection::mojom::BarcodeDetectorOptionsPtr options) override;
   void EnumerateSupportedFormats(
       EnumerateSupportedFormatsCallback callback) override;
diff --git a/services/shape_detection/barcode_detection_provider_mac.h b/services/shape_detection/barcode_detection_provider_mac.h
index 7dcdf6b..0fa741b 100644
--- a/services/shape_detection/barcode_detection_provider_mac.h
+++ b/services/shape_detection/barcode_detection_provider_mac.h
@@ -32,7 +32,7 @@
   static void Create(mojom::BarcodeDetectionProviderRequest request);
 
   void CreateBarcodeDetection(
-      mojom::BarcodeDetectionRequest request,
+      mojo::PendingReceiver<mojom::BarcodeDetection> receiver,
       mojom::BarcodeDetectorOptionsPtr options) override;
   void EnumerateSupportedFormats(
       EnumerateSupportedFormatsCallback callback) override;
diff --git a/services/shape_detection/barcode_detection_provider_mac.mm b/services/shape_detection/barcode_detection_provider_mac.mm
index e0ea204..31c017b7 100644
--- a/services/shape_detection/barcode_detection_provider_mac.mm
+++ b/services/shape_detection/barcode_detection_provider_mac.mm
@@ -8,7 +8,7 @@
 #include <utility>
 
 #include "base/logging.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "services/shape_detection/barcode_detection_impl_mac.h"
 #include "services/shape_detection/barcode_detection_impl_mac_vision.h"
 
@@ -29,7 +29,7 @@
 }
 
 void BarcodeDetectionProviderMac::CreateBarcodeDetection(
-    mojom::BarcodeDetectionRequest request,
+    mojo::PendingReceiver<mojom::BarcodeDetection> receiver,
     mojom::BarcodeDetectorOptionsPtr options) {
   if (!vision_api_)
     vision_api_ = VisionAPIInterface::Create();
@@ -40,14 +40,15 @@
       auto impl =
           std::make_unique<BarcodeDetectionImplMacVision>(std::move(options));
       auto* impl_ptr = impl.get();
-      impl_ptr->SetBinding(
-          mojo::MakeStrongBinding(std::move(impl), std::move(request)));
+      impl_ptr->SetBinding(mojo::MakeStrongBinding(
+          std::move(impl),
+          mojo::InterfaceRequest<mojom::BarcodeDetection>(receiver)));
       return;
     }
   }
 
-  mojo::MakeStrongBinding(std::make_unique<BarcodeDetectionImplMac>(),
-                          std::move(request));
+  mojo::MakeSelfOwnedReceiver(std::make_unique<BarcodeDetectionImplMac>(),
+                              std::move(receiver));
 }
 
 void BarcodeDetectionProviderMac::EnumerateSupportedFormats(
diff --git a/services/shape_detection/barcode_detection_provider_mac_unittest.mm b/services/shape_detection/barcode_detection_provider_mac_unittest.mm
index 1ee616f4..2eb5e6f4 100644
--- a/services/shape_detection/barcode_detection_provider_mac_unittest.mm
+++ b/services/shape_detection/barcode_detection_provider_mac_unittest.mm
@@ -14,6 +14,7 @@
 #include "base/run_loop.h"
 #include "base/test/bind_test_util.h"
 #include "base/test/task_environment.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
 #include "services/shape_detection/barcode_detection_impl_mac_vision.h"
@@ -238,13 +239,12 @@
   mojo::MakeStrongBinding(CreateBarcodeProviderMac(CreateVisionAPI()),
                           std::move(provider_request));
 
-  mojom::BarcodeDetectionPtr impl;
-  auto impl_request = mojo::MakeRequest(&impl);
   auto options = mojom::BarcodeDetectorOptions::New();
   options->formats = {mojom::BarcodeFormat::UNKNOWN};
 
   mojo::test::BadMessageObserver observer;
-  provider_ptr->CreateBarcodeDetection(std::move(impl_request),
+  mojo::Remote<mojom::BarcodeDetection> impl;
+  provider_ptr->CreateBarcodeDetection(impl.BindNewPipeAndPassReceiver(),
                                        std::move(options));
 
   EXPECT_EQ("Formats hint contains UNKNOWN BarcodeFormat.",
diff --git a/services/shape_detection/public/mojom/barcodedetection_provider.mojom b/services/shape_detection/public/mojom/barcodedetection_provider.mojom
index 65937d3..d6fb7e0 100644
--- a/services/shape_detection/public/mojom/barcodedetection_provider.mojom
+++ b/services/shape_detection/public/mojom/barcodedetection_provider.mojom
@@ -14,7 +14,7 @@
 };
 
 interface BarcodeDetectionProvider {
-  CreateBarcodeDetection(BarcodeDetection& request,
+  CreateBarcodeDetection(pending_receiver<BarcodeDetection> receiver,
                          BarcodeDetectorOptions options);
 
   EnumerateSupportedFormats() => (array<BarcodeFormat> supported_formats);
diff --git a/services/tracing/agent_registry.cc b/services/tracing/agent_registry.cc
index 30e38ae..a16ba32 100644
--- a/services/tracing/agent_registry.cc
+++ b/services/tracing/agent_registry.cc
@@ -20,7 +20,7 @@
 
 AgentRegistry::AgentEntry::AgentEntry(size_t id,
                                       AgentRegistry* agent_registry,
-                                      mojom::AgentPtr agent,
+                                      mojo::PendingRemote<mojom::Agent> agent,
                                       const std::string& label,
                                       mojom::TraceDataType type,
                                       base::ProcessId pid)
@@ -31,7 +31,7 @@
       type_(type),
       pid_(pid) {
   DCHECK(!label.empty());
-  agent_.set_connection_error_handler(base::BindRepeating(
+  agent_.set_disconnect_handler(base::BindRepeating(
       &AgentRegistry::AgentEntry::OnConnectionError, AsWeakPtr()));
 }
 
@@ -81,12 +81,12 @@
 AgentRegistry::~AgentRegistry() = default;
 
 void AgentRegistry::DisconnectAllAgents() {
-  bindings_.CloseAllBindings();
+  receivers_.Clear();
 }
 
-void AgentRegistry::BindAgentRegistryRequest(
-    mojom::AgentRegistryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+void AgentRegistry::BindAgentRegistryReceiver(
+    mojo::PendingReceiver<mojom::AgentRegistry> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 size_t AgentRegistry::SetAgentInitializationCallback(
@@ -111,7 +111,7 @@
   return false;
 }
 
-void AgentRegistry::RegisterAgent(mojom::AgentPtr agent,
+void AgentRegistry::RegisterAgent(mojo::PendingRemote<mojom::Agent> agent,
                                   const std::string& label,
                                   mojom::TraceDataType type,
                                   base::ProcessId pid) {
diff --git a/services/tracing/agent_registry.h b/services/tracing/agent_registry.h
index cb701f3..3192b74e 100644
--- a/services/tracing/agent_registry.h
+++ b/services/tracing/agent_registry.h
@@ -13,7 +13,8 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/timer/timer.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/service_manager/public/cpp/identity.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
@@ -25,7 +26,7 @@
    public:
     AgentEntry(size_t id,
                AgentRegistry* agent_registry,
-               mojom::AgentPtr agent,
+               mojo::PendingRemote<mojom::Agent> agent,
                const std::string& label,
                mojom::TraceDataType type,
                base::ProcessId pid);
@@ -49,7 +50,7 @@
 
     const size_t id_;
     AgentRegistry* agent_registry_;
-    mojom::AgentPtr agent_;
+    mojo::Remote<mojom::Agent> agent_;
     const std::string label_;
     const mojom::TraceDataType type_;
     const base::ProcessId pid_;
@@ -68,8 +69,8 @@
 
   void DisconnectAllAgents();
 
-  void BindAgentRegistryRequest(
-      mojom::AgentRegistryRequest request);
+  void BindAgentRegistryReceiver(
+      mojo::PendingReceiver<mojom::AgentRegistry> receiver);
 
   // Returns the number of existing agents that the callback was run on.
   size_t SetAgentInitializationCallback(
@@ -89,14 +90,14 @@
   friend class CoordinatorTestUtil;  // For testing.
 
   // mojom::AgentRegistry
-  void RegisterAgent(mojom::AgentPtr agent,
+  void RegisterAgent(mojo::PendingRemote<mojom::Agent> agent,
                      const std::string& label,
                      mojom::TraceDataType type,
                      base::ProcessId pid) override;
 
   void UnregisterAgent(size_t agent_id);
 
-  mojo::BindingSet<mojom::AgentRegistry> bindings_;
+  mojo::ReceiverSet<mojom::AgentRegistry> receivers_;
   size_t next_agent_id_ = 0;
   std::map<size_t, std::unique_ptr<AgentEntry>> agents_;
   AgentInitializationCallback agent_initialization_callback_;
diff --git a/services/tracing/agent_registry_unittest.cc b/services/tracing/agent_registry_unittest.cc
index 70fa52f..b6bc6e6 100644
--- a/services/tracing/agent_registry_unittest.cc
+++ b/services/tracing/agent_registry_unittest.cc
@@ -30,14 +30,14 @@
     message_loop_.reset();
   }
 
-  void RegisterAgent(mojom::AgentPtr agent,
+  void RegisterAgent(mojo::PendingRemote<mojom::Agent> agent,
                      const std::string& label,
                      mojom::TraceDataType type) {
     registry_->RegisterAgent(std::move(agent), label, type,
                              base::kNullProcessId);
   }
 
-  void RegisterAgent(mojom::AgentPtr agent) {
+  void RegisterAgent(mojo::PendingRemote<mojom::Agent> agent) {
     registry_->RegisterAgent(std::move(agent), "label",
                              mojom::TraceDataType::ARRAY, base::kNullProcessId);
   }
@@ -50,7 +50,7 @@
 
 TEST_F(AgentRegistryTest, RegisterAgent) {
   MockAgent agent1;
-  RegisterAgent(agent1.CreateAgentPtr(), "TraceEvent",
+  RegisterAgent(agent1.CreateAgentRemote(), "TraceEvent",
                 mojom::TraceDataType::ARRAY);
   size_t num_agents = 0;
   registry_->ForAllAgents([&num_agents](AgentRegistry::AgentEntry* entry) {
@@ -61,7 +61,8 @@
   EXPECT_EQ(1u, num_agents);
 
   MockAgent agent2;
-  RegisterAgent(agent2.CreateAgentPtr(), "Power", mojom::TraceDataType::STRING);
+  RegisterAgent(agent2.CreateAgentRemote(), "Power",
+                mojom::TraceDataType::STRING);
   num_agents = 0;
   registry_->ForAllAgents([&num_agents](AgentRegistry::AgentEntry* entry) {
     num_agents++;
@@ -77,10 +78,10 @@
 TEST_F(AgentRegistryTest, UnregisterAgent) {
   base::RunLoop run_loop;
   MockAgent agent1;
-  RegisterAgent(agent1.CreateAgentPtr());
+  RegisterAgent(agent1.CreateAgentRemote());
   {
     MockAgent agent2;
-    RegisterAgent(agent2.CreateAgentPtr());
+    RegisterAgent(agent2.CreateAgentRemote());
     size_t num_agents = 0;
     registry_->ForAllAgents(
         [&num_agents](AgentRegistry::AgentEntry* entry) { num_agents++; });
@@ -98,7 +99,7 @@
 TEST_F(AgentRegistryTest, AgentInitialization) {
   size_t num_calls = 0;
   MockAgent agent1;
-  RegisterAgent(agent1.CreateAgentPtr());
+  RegisterAgent(agent1.CreateAgentRemote());
   size_t num_initialized_agents = registry_->SetAgentInitializationCallback(
       base::BindRepeating(
           [](size_t* num_calls, tracing::AgentRegistry::AgentEntry* entry) {
@@ -112,7 +113,7 @@
 
   // The callback should be run on future agents, too.
   MockAgent agent2;
-  RegisterAgent(agent2.CreateAgentPtr());
+  RegisterAgent(agent2.CreateAgentRemote());
   EXPECT_EQ(2u, num_calls);
 }
 
diff --git a/services/tracing/coordinator.cc b/services/tracing/coordinator.cc
index 328c044..cdf9d51 100644
--- a/services/tracing/coordinator.cc
+++ b/services/tracing/coordinator.cc
@@ -278,7 +278,6 @@
     : task_runner_(base::SequencedTaskRunnerHandle::Get()),
       agent_registry_(agent_registry),
       on_disconnect_callback_(std::move(on_disconnect_callback)),
-      binding_(this),
       // USER_VISIBLE because the task posted from StopAndFlushInternal() is
       // required to stop tracing from the UI.
       // TODO(fdoray): Once we have support for dynamic priorities
@@ -295,7 +294,7 @@
 }
 
 bool Coordinator::IsConnected() {
-  return !!binding_;
+  return receiver_.is_bound();
 }
 
 void Coordinator::Reset() {
@@ -324,14 +323,14 @@
 
 void Coordinator::OnClientConnectionError() {
   Reset();
-  binding_.Close();
+  receiver_.reset();
   on_disconnect_callback_.Run();
 }
 void Coordinator::BindCoordinatorRequest(
-    mojom::CoordinatorRequest request,
+    mojo::PendingReceiver<mojom::Coordinator> receiver,
     const service_manager::BindSourceInfo& source_info) {
-  binding_.Bind(std::move(request));
-  binding_.set_connection_error_handler(base::BindRepeating(
+  receiver_.Bind(std::move(receiver));
+  receiver_.set_disconnect_handler(base::BindRepeating(
       &Coordinator::OnClientConnectionError, base::Unretained(this)));
 }
 
diff --git a/services/tracing/coordinator.h b/services/tracing/coordinator.h
index 0b4d3b7..5b6e42a 100644
--- a/services/tracing/coordinator.h
+++ b/services/tracing/coordinator.h
@@ -17,6 +17,7 @@
 #include "base/timer/timer.h"
 #include "base/trace_event/trace_config.h"
 #include "base/values.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "services/tracing/agent_registry.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
@@ -46,7 +47,7 @@
               const base::RepeatingClosure& on_disconnect_callback);
 
   void BindCoordinatorRequest(
-      mojom::CoordinatorRequest request,
+      mojo::PendingReceiver<mojom::Coordinator> request,
       const service_manager::BindSourceInfo& source_info);
 
   bool IsConnected();
@@ -106,7 +107,7 @@
                                      uint32_t count);
 
   base::RepeatingClosure on_disconnect_callback_;
-  mojo::Binding<mojom::Coordinator> binding_;
+  mojo::Receiver<mojom::Coordinator> receiver_{this};
   const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
   std::string config_;
   bool is_tracing_ = false;
diff --git a/services/tracing/coordinator_test_util.cc b/services/tracing/coordinator_test_util.cc
index 41bdee5..01df6f8 100644
--- a/services/tracing/coordinator_test_util.cc
+++ b/services/tracing/coordinator_test_util.cc
@@ -46,7 +46,7 @@
 
 MockAgent* CoordinatorTestUtil::AddArrayAgent(base::ProcessId pid) {
   auto agent = std::make_unique<MockAgent>();
-  agent_registry_->RegisterAgent(agent->CreateAgentPtr(), "traceEvents",
+  agent_registry_->RegisterAgent(agent->CreateAgentRemote(), "traceEvents",
                                  mojom::TraceDataType::ARRAY, pid);
   agents_.push_back(std::move(agent));
   return agents_.back().get();
@@ -58,16 +58,16 @@
 
 MockAgent* CoordinatorTestUtil::AddObjectAgent() {
   auto agent = std::make_unique<MockAgent>();
-  agent_registry_->RegisterAgent(agent->CreateAgentPtr(), "systemTraceEvents",
-                                 mojom::TraceDataType::OBJECT,
-                                 base::kNullProcessId);
+  agent_registry_->RegisterAgent(
+      agent->CreateAgentRemote(), "systemTraceEvents",
+      mojom::TraceDataType::OBJECT, base::kNullProcessId);
   agents_.push_back(std::move(agent));
   return agents_.back().get();
 }
 
 MockAgent* CoordinatorTestUtil::AddStringAgent() {
   auto agent = std::make_unique<MockAgent>();
-  agent_registry_->RegisterAgent(agent->CreateAgentPtr(), "power",
+  agent_registry_->RegisterAgent(agent->CreateAgentRemote(), "power",
                                  mojom::TraceDataType::STRING,
                                  base::kNullProcessId);
   agents_.push_back(std::move(agent));
diff --git a/services/tracing/perfetto/perfetto_tracing_coordinator.cc b/services/tracing/perfetto/perfetto_tracing_coordinator.cc
index 65635555..3c658c3 100644
--- a/services/tracing/perfetto/perfetto_tracing_coordinator.cc
+++ b/services/tracing/perfetto/perfetto_tracing_coordinator.cc
@@ -240,8 +240,7 @@
 PerfettoTracingCoordinator::PerfettoTracingCoordinator(
     AgentRegistry* agent_registry,
     base::RepeatingClosure on_disconnect_callback)
-    : Coordinator(agent_registry, std::move(on_disconnect_callback)),
-      binding_(this) {
+    : Coordinator(agent_registry, std::move(on_disconnect_callback)) {
   DETACH_FROM_SEQUENCE(sequence_checker_);
 }
 
@@ -252,15 +251,15 @@
 void PerfettoTracingCoordinator::OnClientConnectionError() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   tracing_session_.reset();
-  binding_.Close();
+  receiver_.reset();
   Coordinator::OnClientConnectionError();
 }
 
-void PerfettoTracingCoordinator::BindCoordinatorRequest(
-    mojom::CoordinatorRequest request,
+void PerfettoTracingCoordinator::BindCoordinatorReceiver(
+    mojo::PendingReceiver<mojom::Coordinator> receiver,
     const service_manager::BindSourceInfo& source_info) {
-  binding_.Bind(std::move(request));
-  binding_.set_connection_error_handler(
+  receiver_.Bind(std::move(receiver));
+  receiver_.set_disconnect_handler(
       base::BindOnce(&PerfettoTracingCoordinator::OnClientConnectionError,
                      base::Unretained(this)));
 }
diff --git a/services/tracing/perfetto/perfetto_tracing_coordinator.h b/services/tracing/perfetto/perfetto_tracing_coordinator.h
index 0bc350e..6eb7f83 100644
--- a/services/tracing/perfetto/perfetto_tracing_coordinator.h
+++ b/services/tracing/perfetto/perfetto_tracing_coordinator.h
@@ -10,7 +10,6 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "services/tracing/coordinator.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
@@ -31,8 +30,8 @@
 
   ~PerfettoTracingCoordinator() override;
 
-  void BindCoordinatorRequest(
-      mojom::CoordinatorRequest request,
+  void BindCoordinatorReceiver(
+      mojo::PendingReceiver<mojom::Coordinator> receiver,
       const service_manager::BindSourceInfo& source_info);
 
   // mojom::Coordinator implementation.
@@ -57,7 +56,7 @@
                             const std::string& agent_label,
                             StopAndFlushCallback callback);
 
-  mojo::Binding<mojom::Coordinator> binding_;
+  mojo::Receiver<mojom::Coordinator> receiver_{this};
 
   class TracingSession;
   std::unique_ptr<TracingSession> tracing_session_;
diff --git a/services/tracing/public/cpp/base_agent.cc b/services/tracing/public/cpp/base_agent.cc
index ee7ac41..8250ead 100644
--- a/services/tracing/public/cpp/base_agent.cc
+++ b/services/tracing/public/cpp/base_agent.cc
@@ -16,7 +16,7 @@
 BaseAgent::BaseAgent(const std::string& label,
                      mojom::TraceDataType type,
                      base::ProcessId pid)
-    : binding_(this), label_(label), type_(type), pid_(pid) {
+    : label_(label), type_(type), pid_(pid) {
   TracedProcessImpl::GetInstance()->RegisterAgent(this);
 }
 
@@ -25,9 +25,9 @@
 }
 
 void BaseAgent::Connect(tracing::mojom::AgentRegistry* agent_registry) {
-  tracing::mojom::AgentPtr agent;
-  binding_.Bind(mojo::MakeRequest(&agent));
-  binding_.set_connection_error_handler(
+  mojo::PendingRemote<tracing::mojom::Agent> agent;
+  receiver_.Bind(agent.InitWithNewPipeAndPassReceiver());
+  receiver_.set_disconnect_handler(
       base::BindRepeating(&BaseAgent::Disconnect, base::Unretained(this)));
 
   agent_registry->RegisterAgent(std::move(agent), label_, type_, pid_);
@@ -36,7 +36,7 @@
 void BaseAgent::GetCategories(std::set<std::string>* category_set) {}
 
 void BaseAgent::Disconnect() {
-  binding_.Close();
+  receiver_.reset();
 
   // If we get disconnected it means the tracing service went down, most likely
   // due to the process dying. In that case, stop any tracing in progress.
@@ -60,7 +60,7 @@
 }
 
 bool BaseAgent::IsBoundForTesting() const {
-  return binding_.is_bound();
+  return receiver_.is_bound();
 }
 
 }  // namespace tracing
diff --git a/services/tracing/public/cpp/base_agent.h b/services/tracing/public/cpp/base_agent.h
index b421df1..4aa86b4 100644
--- a/services/tracing/public/cpp/base_agent.h
+++ b/services/tracing/public/cpp/base_agent.h
@@ -9,7 +9,7 @@
 #include <string>
 
 #include "base/component_export.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
 // This class is a minimal implementation of mojom::Agent to reduce boilerplate
@@ -43,7 +43,7 @@
   void RequestBufferStatus(
       Agent::RequestBufferStatusCallback callback) override;
 
-  mojo::Binding<tracing::mojom::Agent> binding_;
+  mojo::Receiver<tracing::mojom::Agent> receiver_{this};
 
   const std::string label_;
   const mojom::TraceDataType type_;
diff --git a/services/tracing/public/cpp/traced_process_impl.cc b/services/tracing/public/cpp/traced_process_impl.cc
index 93f586a..f9c9412c 100644
--- a/services/tracing/public/cpp/traced_process_impl.cc
+++ b/services/tracing/public/cpp/traced_process_impl.cc
@@ -91,11 +91,11 @@
   // Ensure the TraceEventAgent has been created.
   TraceEventAgent::GetInstance();
 
-  agent_registry_ =
-      tracing::mojom::AgentRegistryPtr(std::move(request->agent_registry));
-  agent_registry_.set_connection_error_handler(base::BindRepeating(
+  agent_registry_ = mojo::Remote<tracing::mojom::AgentRegistry>(
+      std::move(request->agent_registry));
+  agent_registry_.set_disconnect_handler(base::BindRepeating(
       [](TracedProcessImpl* traced_process) {
-        // If the AgentRegistryPtr connection closes, the tracing service
+        // If the AgentRegistry connection closes, the tracing service
         // has gone down and we'll start accepting new connections from it
         // again.
         base::AutoLock lock(traced_process->lock_);
diff --git a/services/tracing/public/cpp/traced_process_impl.h b/services/tracing/public/cpp/traced_process_impl.h
index a67e2ca..946d3b87 100644
--- a/services/tracing/public/cpp/traced_process_impl.h
+++ b/services/tracing/public/cpp/traced_process_impl.h
@@ -12,6 +12,7 @@
 #include "base/sequence_checker.h"
 #include "base/synchronization/lock.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/tracing/public/mojom/traced_process.mojom.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
@@ -52,7 +53,7 @@
   // Lock protecting binding_.
   base::Lock lock_;
   std::set<BaseAgent*> agents_;
-  tracing::mojom::AgentRegistryPtr agent_registry_;
+  mojo::Remote<tracing::mojom::AgentRegistry> agent_registry_;
   mojo::Binding<tracing::mojom::TracedProcess> binding_;
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
diff --git a/services/tracing/public/mojom/tracing.mojom b/services/tracing/public/mojom/tracing.mojom
index 3c282c4..c846c62 100644
--- a/services/tracing/public/mojom/tracing.mojom
+++ b/services/tracing/public/mojom/tracing.mojom
@@ -30,7 +30,7 @@
 // data to the service, we do not want to let an untrusted child process be able
 // to collect traces from other processes using the |Coordinator| interface.
 interface AgentRegistry {
-  RegisterAgent(Agent agent, string label, TraceDataType type,
+  RegisterAgent(pending_remote<Agent> agent, string label, TraceDataType type,
                 mojo_base.mojom.ProcessId pid);
 };
 
diff --git a/services/tracing/test_util.cc b/services/tracing/test_util.cc
index fe0b288..94dd4c1 100644
--- a/services/tracing/test_util.cc
+++ b/services/tracing/test_util.cc
@@ -11,13 +11,13 @@
 
 namespace tracing {
 
-MockAgent::MockAgent() : binding_(this) {}
+MockAgent::MockAgent() {}
 
 MockAgent::~MockAgent() = default;
 
-mojom::AgentPtr MockAgent::CreateAgentPtr() {
-  mojom::AgentPtr agent_proxy;
-  binding_.Bind(mojo::MakeRequest(&agent_proxy));
+mojo::PendingRemote<mojom::Agent> MockAgent::CreateAgentRemote() {
+  mojo::PendingRemote<mojom::Agent> agent_proxy;
+  receiver_.Bind(agent_proxy.InitWithNewPipeAndPassReceiver());
   return agent_proxy;
 }
 
diff --git a/services/tracing/test_util.h b/services/tracing/test_util.h
index 821a7eb0..e43e051 100644
--- a/services/tracing/test_util.h
+++ b/services/tracing/test_util.h
@@ -10,7 +10,8 @@
 
 #include "base/trace_event/trace_log.h"
 #include "base/values.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
 namespace base {
@@ -24,7 +25,7 @@
   MockAgent();
   ~MockAgent() override;
 
-  mojom::AgentPtr CreateAgentPtr();
+  mojo::PendingRemote<mojom::Agent> CreateAgentRemote();
 
   std::vector<std::string> call_stat() const { return call_stat_; }
 
@@ -42,7 +43,7 @@
   void StopAndFlush(mojom::RecorderPtr recorder) override;
   void RequestBufferStatus(RequestBufferStatusCallback cb) override;
 
-  mojo::Binding<mojom::Agent> binding_;
+  mojo::Receiver<mojom::Agent> receiver_{this};
   std::vector<std::string> call_stat_;
 };
 
diff --git a/services/tracing/tracing_service.cc b/services/tracing/tracing_service.cc
index 1075972..7b24864 100644
--- a/services/tracing/tracing_service.cc
+++ b/services/tracing/tracing_service.cc
@@ -140,10 +140,11 @@
       service_manager::mojom::RunningServiceInfoPtr service) override {}
 
  private:
-  void OnProcessConnected(mojom::TracedProcessPtr traced_process,
-                          uint32_t pid,
-                          mojom::PerfettoServiceRequest service_request,
-                          mojom::AgentRegistryRequest registry_request) {
+  void OnProcessConnected(
+      mojom::TracedProcessPtr traced_process,
+      uint32_t pid,
+      mojom::PerfettoServiceRequest service_request,
+      mojo::PendingReceiver<mojom::AgentRegistry> registry_receiver) {
     auto result = connected_pids_.insert(pid);
     if (!result.second) {
       // The PID was already connected. Nothing more to do.
@@ -153,7 +154,7 @@
     connected_pids_.insert(pid);
     PerfettoService::GetInstance()->BindRequest(std::move(service_request),
                                                 pid);
-    agent_registry_->BindAgentRegistryRequest(std::move(registry_request));
+    agent_registry_->BindAgentRegistryReceiver(std::move(registry_receiver));
   }
 
   mojo::Binding<service_manager::mojom::ServiceManagerListener> binding_{this};
diff --git a/third_party/blink/public/mojom/leak_detector/leak_detector.mojom b/third_party/blink/public/mojom/leak_detector/leak_detector.mojom
index 1120c12b..bdfb0082 100644
--- a/third_party/blink/public/mojom/leak_detector/leak_detector.mojom
+++ b/third_party/blink/public/mojom/leak_detector/leak_detector.mojom
@@ -12,7 +12,6 @@
   uint32 number_of_live_layout_objects;
   uint32 number_of_live_resources;
   uint32 number_of_live_context_lifecycle_state_observers;
-  uint32 number_of_live_script_promises;
   uint32 number_of_live_frames;
   uint32 number_of_live_v8_per_context_data;
   uint32 number_of_worker_global_scopes;
diff --git a/third_party/blink/public/web/web_security_policy.h b/third_party/blink/public/web/web_security_policy.h
index fb3b59c..6e1a9e11 100644
--- a/third_party/blink/public/web/web_security_policy.h
+++ b/third_party/blink/public/web/web_security_policy.h
@@ -34,6 +34,7 @@
 #include "services/network/public/mojom/cors_origin_pattern.mojom-shared.h"
 #include "services/network/public/mojom/referrer_policy.mojom-shared.h"
 #include "third_party/blink/public/platform/web_common.h"
+#include "third_party/blink/public/platform/web_security_origin.h"
 
 namespace blink {
 
@@ -108,6 +109,7 @@
   // referrer header should be omitted.
   BLINK_EXPORT static WebString GenerateReferrerHeader(
       network::mojom::ReferrerPolicy,
+      const WebSecurityOrigin& origin,
       const WebURL&,
       const WebString& referrer);
 
diff --git a/third_party/blink/renderer/bindings/core/v8/iterable.h b/third_party/blink/renderer/bindings/core/v8/iterable.h
index 0d89cfa..109a120 100644
--- a/third_party/blink/renderer/bindings/core/v8/iterable.h
+++ b/third_party/blink/renderer/bindings/core/v8/iterable.h
@@ -120,14 +120,14 @@
   };
   struct EntrySelector {
     STATIC_ONLY(EntrySelector);
-    static Vector<ScriptValue, 2> Select(ScriptState* script_state,
-                                         const KeyType& key,
-                                         const ValueType& value) {
+    static HeapVector<ScriptValue, 2> Select(ScriptState* script_state,
+                                             const KeyType& key,
+                                             const ValueType& value) {
       v8::Local<v8::Object> creation_context =
           script_state->GetContext()->Global();
       v8::Isolate* isolate = script_state->GetIsolate();
 
-      Vector<ScriptValue, 2> entry;
+      HeapVector<ScriptValue, 2> entry;
       entry.push_back(
           ScriptValue(script_state, ToV8(key, creation_context, isolate)));
       entry.push_back(
diff --git a/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc b/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc
index 6d8b70d..8e525d16 100644
--- a/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc
+++ b/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc
@@ -88,7 +88,7 @@
   //   If an exception gets thrown by the callback, end these steps and allow
   //   the exception to propagate. (It will propagate to the DOM event dispatch
   //   logic, which will then report the exception.)
-  Vector<ScriptValue> arguments;
+  HeapVector<ScriptValue> arguments;
   ScriptState* script_state_of_listener =
       event_handler_->CallbackRelevantScriptState();
 
diff --git a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc
index 4004a72..7ea955c 100644
--- a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc
@@ -259,7 +259,7 @@
         EvaluateScriptForArray(scope, "['Vini, vidi, vici.', 65535, 0.125]");
 
     NonThrowableExceptionState exception_state;
-    Vector<ScriptValue> script_value_vector =
+    HeapVector<ScriptValue> script_value_vector =
         NativeValueTraits<IDLSequence<ScriptValue>>::NativeValue(
             scope.GetIsolate(), v8_array, exception_state);
     EXPECT_EQ(3U, script_value_vector.size());
diff --git a/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc b/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
index cb096bd..843cb14 100644
--- a/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
+++ b/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
@@ -51,10 +51,11 @@
 
 namespace blink {
 
-ScheduledAction* ScheduledAction::Create(ScriptState* script_state,
-                                         ExecutionContext* target,
-                                         V8Function* handler,
-                                         const Vector<ScriptValue>& arguments) {
+ScheduledAction* ScheduledAction::Create(
+    ScriptState* script_state,
+    ExecutionContext* target,
+    V8Function* handler,
+    const HeapVector<ScriptValue>& arguments) {
   if (!script_state->World().IsWorkerWorld()) {
     if (!BindingSecurity::ShouldAllowAccessToFrame(
             EnteredDOMWindow(script_state->GetIsolate()),
@@ -85,7 +86,7 @@
 
 ScheduledAction::ScheduledAction(ScriptState* script_state,
                                  V8Function* function,
-                                 const Vector<ScriptValue>& arguments)
+                                 const HeapVector<ScriptValue>& arguments)
     : script_state_(
           MakeGarbageCollected<ScriptStateProtectingContext>(script_state)),
       function_(function),
@@ -157,6 +158,7 @@
 void ScheduledAction::Trace(blink::Visitor* visitor) {
   visitor->Trace(script_state_);
   visitor->Trace(function_);
+  visitor->Trace(arguments_);
 }
 
 void ScheduledAction::Execute(LocalFrame* frame) {
diff --git a/third_party/blink/renderer/bindings/core/v8/scheduled_action.h b/third_party/blink/renderer/bindings/core/v8/scheduled_action.h
index 5c6de14..e494d92 100644
--- a/third_party/blink/renderer/bindings/core/v8/scheduled_action.h
+++ b/third_party/blink/renderer/bindings/core/v8/scheduled_action.h
@@ -55,14 +55,14 @@
   static ScheduledAction* Create(ScriptState*,
                                  ExecutionContext* target,
                                  V8Function* handler,
-                                 const Vector<ScriptValue>& arguments);
+                                 const HeapVector<ScriptValue>& arguments);
   static ScheduledAction* Create(ScriptState*,
                                  ExecutionContext* target,
                                  const String& handler);
 
   explicit ScheduledAction(ScriptState*,
                            V8Function* handler,
-                           const Vector<ScriptValue>& arguments);
+                           const HeapVector<ScriptValue>& arguments);
   explicit ScheduledAction(ScriptState*, const String& handler);
   // Creates an empty ScheduledAction.
   explicit ScheduledAction(ScriptState*);
@@ -83,7 +83,7 @@
 
   Member<ScriptStateProtectingContext> script_state_;
   Member<V8Function> function_;
-  Vector<ScriptValue> arguments_;
+  HeapVector<ScriptValue> arguments_;
   String code_;
 };
 
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise.cc b/third_party/blink/renderer/bindings/core/v8/script_promise.cc
index b031ff084..b6b6929e 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise.cc
@@ -36,7 +36,6 @@
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
-#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
 #include "v8/include/v8.h"
 
 namespace blink {
@@ -47,7 +46,7 @@
     : public GarbageCollectedFinalized<PromiseAllHandler> {
  public:
   static ScriptPromise All(ScriptState* script_state,
-                           const Vector<ScriptPromise>& promises) {
+                           const HeapVector<ScriptPromise>& promises) {
     if (promises.IsEmpty())
       return ScriptPromise::Cast(script_state,
                                  v8::Array::New(script_state->GetIsolate()));
@@ -55,7 +54,8 @@
         ->resolver_.Promise();
   }
 
-  PromiseAllHandler(ScriptState* script_state, Vector<ScriptPromise> promises)
+  PromiseAllHandler(ScriptState* script_state,
+                    HeapVector<ScriptPromise> promises)
       : number_of_pending_promises_(promises.size()), resolver_(script_state) {
     DCHECK(!promises.IsEmpty());
     values_.resize(promises.size());
@@ -65,7 +65,10 @@
     }
   }
 
-  virtual void Trace(blink::Visitor* visitor) { visitor->Trace(resolver_); }
+  virtual void Trace(blink::Visitor* visitor) {
+    visitor->Trace(resolver_);
+    visitor->Trace(values_);
+  }
 
  private:
   class AdapterFunction : public ScriptFunction {
@@ -157,7 +160,7 @@
 
   // This is cleared when owners of this handler, that is, given promises are
   // settled.
-  Vector<ScriptValue> values_;
+  HeapVector<ScriptValue> values_;
 
   DISALLOW_COPY_AND_ASSIGN(PromiseAllHandler);
 };
@@ -210,15 +213,9 @@
   Clear();
 }
 
-ScriptPromise::ScriptPromise() {
-  IncreaseInstanceCount();
-}
-
 ScriptPromise::ScriptPromise(ScriptState* script_state,
                              v8::Local<v8::Value> value)
     : script_state_(script_state) {
-  IncreaseInstanceCount();
-
   if (value.IsEmpty())
     return;
 
@@ -232,16 +229,10 @@
 }
 
 ScriptPromise::ScriptPromise(const ScriptPromise& other) {
-  IncreaseInstanceCount();
-
   this->script_state_ = other.script_state_;
   this->promise_ = other.promise_;
 }
 
-ScriptPromise::~ScriptPromise() {
-  DecreaseInstanceCount();
-}
-
 ScriptPromise ScriptPromise::Then(v8::Local<v8::Function> on_fulfilled,
                                   v8::Local<v8::Function> on_rejected) {
   if (promise_.IsEmpty())
@@ -350,16 +341,8 @@
 }
 
 ScriptPromise ScriptPromise::All(ScriptState* script_state,
-                                 const Vector<ScriptPromise>& promises) {
+                                 const HeapVector<ScriptPromise>& promises) {
   return PromiseAllHandler::All(script_state, promises);
 }
 
-void ScriptPromise::IncreaseInstanceCount() {
-  InstanceCounters::IncrementCounter(InstanceCounters::kScriptPromiseCounter);
-}
-
-void ScriptPromise::DecreaseInstanceCount() {
-  InstanceCounters::DecrementCounter(InstanceCounters::kScriptPromiseCounter);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise.h b/third_party/blink/renderer/bindings/core/v8/script_promise.h
index 555de6a..fde92c9 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise.h
@@ -57,7 +57,7 @@
 
  public:
   // Constructs an empty promise.
-  ScriptPromise();
+  ScriptPromise() = default;
 
   // Constructs a ScriptPromise from |promise|.
   // If |promise| is not a Promise object, throws a v8 TypeError.
@@ -65,7 +65,7 @@
 
   ScriptPromise(const ScriptPromise&);
 
-  ~ScriptPromise();
+  ~ScriptPromise() = default;
 
   ScriptPromise Then(v8::Local<v8::Function> on_fulfilled,
                      v8::Local<v8::Function> on_rejected = {});
@@ -121,7 +121,13 @@
   // Constructs and returns a ScriptPromise to be resolved when all |promises|
   // are resolved. If one of |promises| is rejected, the returned
   // ScriptPromise is rejected.
-  static ScriptPromise All(ScriptState*, const Vector<ScriptPromise>& promises);
+  static ScriptPromise All(ScriptState*,
+                           const HeapVector<ScriptPromise>& promises);
+
+  void Trace(Visitor* visitor) {
+    visitor->Trace(promise_);
+    visitor->Trace(script_state_);
+  }
 
   // This is a utility class intended to be used internally.
   // ScriptPromiseResolver is for general purpose.
@@ -136,7 +142,10 @@
     void Reject(v8::Local<v8::Value>);
     void Clear() { resolver_.Clear(); }
     ScriptState* GetScriptState() const { return script_state_; }
-    void Trace(blink::Visitor* visitor) { visitor->Trace(script_state_); }
+    void Trace(blink::Visitor* visitor) {
+      visitor->Trace(script_state_);
+      visitor->Trace(resolver_);
+    }
 
    private:
     Member<ScriptState> script_state_;
@@ -147,12 +156,21 @@
   static void IncreaseInstanceCount();
   static void DecreaseInstanceCount();
 
-  // TODO(peria): Move ScriptPromise to Oilpan heap.
-  GC_PLUGIN_IGNORE("813731")
-  Persistent<ScriptState> script_state_;
+  Member<ScriptState> script_state_;
   ScriptValue promise_;
 };
 
 }  // namespace blink
 
+namespace WTF {
+
+template <>
+struct VectorTraits<blink::ScriptPromise>
+    : VectorTraitsBase<blink::ScriptPromise> {
+  STATIC_ONLY(VectorTraits);
+  static constexpr bool kCanClearUnusedSlotsWithMemset = true;
+};
+
+}  // namespace WTF
+
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_PROMISE_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc
index 49e6343..288848e 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc
@@ -371,7 +371,7 @@
   ScriptValue on_fulfilled, on_rejected;
 
   ScriptPromise promise =
-      ScriptPromise::All(scope.GetScriptState(), Vector<ScriptPromise>());
+      ScriptPromise::All(scope.GetScriptState(), HeapVector<ScriptPromise>());
   ASSERT_FALSE(promise.IsEmpty());
 
   promise.Then(FunctionForScriptPromiseTest::CreateFunction(
@@ -393,7 +393,7 @@
   V8TestingScope scope;
   ScriptValue on_fulfilled, on_rejected;
 
-  Vector<ScriptPromise> promises;
+  HeapVector<ScriptPromise> promises;
   promises.push_back(ScriptPromise::Cast(
       scope.GetScriptState(), V8String(scope.GetIsolate(), "hello")));
   promises.push_back(ScriptPromise::Cast(
@@ -423,7 +423,7 @@
   V8TestingScope scope;
   ScriptValue on_fulfilled, on_rejected;
 
-  Vector<ScriptPromise> promises;
+  HeapVector<ScriptPromise> promises;
   promises.push_back(ScriptPromise::Cast(
       scope.GetScriptState(), V8String(scope.GetIsolate(), "hello")));
   promises.push_back(ScriptPromise::Reject(
diff --git a/third_party/blink/renderer/bindings/core/v8/script_value.h b/third_party/blink/renderer/bindings/core/v8/script_value.h
index 3027b1c..5076538 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_value.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_value.h
@@ -164,10 +164,10 @@
 
   static ScriptValue CreateNull(ScriptState*);
 
+  void Trace(Visitor* visitor) { visitor->Trace(script_state_); }
+
  private:
-  // TODO(peria): Move ScriptValue to Oilpan heap.
-  GC_PLUGIN_IGNORE("813731")
-  Persistent<ScriptState> script_state_;
+  Member<ScriptState> script_state_;
   scoped_refptr<SharedPersistent<v8::Value>> value_;
 };
 
@@ -183,4 +183,14 @@
 
 }  // namespace blink
 
+namespace WTF {
+
+template <>
+struct VectorTraits<blink::ScriptValue> : VectorTraitsBase<blink::ScriptValue> {
+  STATIC_ONLY(VectorTraits);
+  static constexpr bool kCanClearUnusedSlotsWithMemset = true;
+};
+
+}  // namespace WTF
+
 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_VALUE_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
index 6a92607..9d6a426 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
@@ -518,7 +518,7 @@
   if (value.IsEmpty() || value->IsUndefined())
     return true;
 
-  const Vector<ScriptValue>& transferable_array =
+  const HeapVector<ScriptValue>& transferable_array =
       NativeValueTraits<IDLSequence<ScriptValue>>::NativeValue(isolate, value,
                                                                exception_state);
   if (exception_state.HadException())
@@ -530,7 +530,7 @@
 
 bool SerializedScriptValue::ExtractTransferables(
     v8::Isolate* isolate,
-    const Vector<ScriptValue>& object_sequence,
+    const HeapVector<ScriptValue>& object_sequence,
     Transferables& transferables,
     ExceptionState& exception_state) {
   // Validate the passed array of transferables.
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
index d1edfe7..58c8eb2 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
@@ -205,7 +205,7 @@
                                    Transferables&,
                                    ExceptionState&);
   static bool ExtractTransferables(v8::Isolate*,
-                                   const Vector<ScriptValue>&,
+                                   const HeapVector<ScriptValue>&,
                                    Transferables&,
                                    ExceptionState&);
 
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
index de2d7f68..a6518b84 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -1850,7 +1850,8 @@
 
   auto* rs = ReadableStream::Create(script_state, ASSERT_NO_EXCEPTION);
   v8::Local<v8::Value> wrapper = ToV8(rs, script_state);
-  Vector<ScriptValue> transferable_array = {ScriptValue(script_state, wrapper)};
+  HeapVector<ScriptValue> transferable_array = {
+      ScriptValue(script_state, wrapper)};
   Transferables transferables;
   ASSERT_TRUE(SerializedScriptValue::ExtractTransferables(
       isolate, transferable_array, transferables, ASSERT_NO_EXCEPTION));
diff --git a/third_party/blink/renderer/bindings/scripts/v8_callback_function.py b/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
index fee066f..bdd5965 100644
--- a/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
+++ b/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
@@ -91,7 +91,10 @@
     def argument_cpp_type(argument):
         cpp_type = argument.idl_type.callback_cpp_type
         if argument.is_variadic:
-            return 'const Vector<%s>&' % cpp_type
+            if argument.idl_type.is_traceable:
+                return 'const HeapVector<%s>&' % cpp_type
+            else:
+                return 'const Vector<%s>&' % cpp_type
         else:
             return cpp_type
 
diff --git a/third_party/blink/renderer/bindings/scripts/v8_types.py b/third_party/blink/renderer/bindings/scripts/v8_types.py
index 3226f36..f14420c 100644
--- a/third_party/blink/renderer/bindings/scripts/v8_types.py
+++ b/third_party/blink/renderer/bindings/scripts/v8_types.py
@@ -209,7 +209,7 @@
     else:
         native_array_element_type = idl_type.native_array_element_type
     if native_array_element_type:
-        vector_type = cpp_ptr_type('Vector', 'HeapVector', native_array_element_type.is_gc_type)
+        vector_type = cpp_ptr_type('Vector', 'HeapVector', native_array_element_type.is_traceable)
         vector_template_type = cpp_template_type(vector_type, native_array_element_type.cpp_type_args(used_in_cpp_sequence=True))
         if used_as_rvalue_type:
             return 'const %s&' % vector_template_type
@@ -217,7 +217,7 @@
 
     # Record types.
     if idl_type.is_record_type:
-        vector_type = cpp_ptr_type('Vector', 'HeapVector', idl_type.value_type.is_gc_type)
+        vector_type = cpp_ptr_type('Vector', 'HeapVector', idl_type.value_type.is_traceable)
         value_type = idl_type.value_type.cpp_type_args(used_in_cpp_sequence=True)
         vector_template_type = cpp_template_type(vector_type,
                                                  'std::pair<String, %s>' % value_type)
@@ -382,7 +382,7 @@
 
 
 def is_traceable(idl_type):
-    return idl_type.is_garbage_collected or idl_type.is_callback_function
+    return idl_type.is_garbage_collected or idl_type.is_callback_function or idl_type.cpp_type in ('ScriptValue', 'ScriptPromise')
 
 IdlTypeBase.is_traceable = property(is_traceable)
 IdlUnionType.is_traceable = property(lambda self: True)
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
index 52c3616..67e69154 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
@@ -35,7 +35,7 @@
 
 TestDictionary::~TestDictionary() = default;
 
-void TestDictionary::setAnyInRecordMember(const Vector<std::pair<String, ScriptValue>>& value) {
+void TestDictionary::setAnyInRecordMember(const HeapVector<std::pair<String, ScriptValue>>& value) {
   any_in_record_member_ = value;
   has_any_in_record_member_ = true;
 }
@@ -203,6 +203,8 @@
 }
 
 void TestDictionary::Trace(blink::Visitor* visitor) {
+  visitor->Trace(any_in_record_member_);
+  visitor->Trace(any_member_);
   visitor->Trace(callback_function_member_);
   visitor->Trace(double_or_null_or_double_or_null_sequence_member_);
   visitor->Trace(double_or_string_member_);
@@ -213,6 +215,8 @@
   visitor->Trace(event_target_member_);
   visitor->Trace(garbage_collected_record_member_);
   visitor->Trace(internal_dictionary_sequence_member_);
+  visitor->Trace(object_member_);
+  visitor->Trace(object_or_null_member_);
   visitor->Trace(other_double_or_string_member_);
   visitor->Trace(required_callback_function_member_);
   visitor->Trace(test_enum_or_null_or_test_enum_sequence_member_);
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h
index 3a16af6..39b10c6 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h
@@ -49,11 +49,11 @@
   virtual ~TestDictionary();
 
   bool hasAnyInRecordMember() const { return has_any_in_record_member_; }
-  const Vector<std::pair<String, ScriptValue>>& anyInRecordMember() const {
+  const HeapVector<std::pair<String, ScriptValue>>& anyInRecordMember() const {
     DCHECK(has_any_in_record_member_);
     return any_in_record_member_;
   }
-  void setAnyInRecordMember(const Vector<std::pair<String, ScriptValue>>&);
+  void setAnyInRecordMember(const HeapVector<std::pair<String, ScriptValue>>&);
 
   bool hasAnyMember() const { return !(any_member_.IsEmpty() || any_member_.IsUndefined()); }
   ScriptValue anyMember() const {
@@ -492,7 +492,7 @@
   bool has_union_or_null_sequence_member_ = false;
   bool has_unrestricted_double_member_ = false;
 
-  Vector<std::pair<String, ScriptValue>> any_in_record_member_;
+  HeapVector<std::pair<String, ScriptValue>> any_in_record_member_;
   ScriptValue any_member_;
   int32_t applicable_to_type_long_member_;
   String applicable_to_type_string_member_;
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_variadic_any_args.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_variadic_any_args.cc
index 58501416..3fa176cc 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_variadic_any_args.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_variadic_any_args.cc
@@ -28,7 +28,7 @@
   return "V8AnyCallbackFunctionVariadicAnyArgs";
 }
 
-v8::Maybe<ScriptValue> V8AnyCallbackFunctionVariadicAnyArgs::Invoke(bindings::V8ValueOrScriptWrappableAdapter callback_this_value, const Vector<ScriptValue>& arguments) {
+v8::Maybe<ScriptValue> V8AnyCallbackFunctionVariadicAnyArgs::Invoke(bindings::V8ValueOrScriptWrappableAdapter callback_this_value, const HeapVector<ScriptValue>& arguments) {
   ScriptState* callback_relevant_script_state =
       CallbackRelevantScriptStateOrThrowException(
           "AnyCallbackFunctionVariadicAnyArgs",
@@ -133,7 +133,7 @@
   }
 }
 
-v8::Maybe<ScriptValue> V8AnyCallbackFunctionVariadicAnyArgs::Construct(const Vector<ScriptValue>& arguments) {
+v8::Maybe<ScriptValue> V8AnyCallbackFunctionVariadicAnyArgs::Construct(const HeapVector<ScriptValue>& arguments) {
   ScriptState* callback_relevant_script_state =
       CallbackRelevantScriptStateOrThrowException(
           "AnyCallbackFunctionVariadicAnyArgs",
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_variadic_any_args.h b/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_variadic_any_args.h
index 0d90338..8b0c012 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_variadic_any_args.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_variadic_any_args.h
@@ -33,11 +33,11 @@
 
   // Performs "invoke".
   // https://heycam.github.io/webidl/#es-invoking-callback-functions
-  v8::Maybe<ScriptValue> Invoke(bindings::V8ValueOrScriptWrappableAdapter callback_this_value, const Vector<ScriptValue>& arguments) WARN_UNUSED_RESULT;
+  v8::Maybe<ScriptValue> Invoke(bindings::V8ValueOrScriptWrappableAdapter callback_this_value, const HeapVector<ScriptValue>& arguments) WARN_UNUSED_RESULT;
 
   // Performs "construct".
   // https://heycam.github.io/webidl/#construct-a-callback-function
-  v8::Maybe<ScriptValue> Construct(const Vector<ScriptValue>& arguments) WARN_UNUSED_RESULT;
+  v8::Maybe<ScriptValue> Construct(const HeapVector<ScriptValue>& arguments) WARN_UNUSED_RESULT;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
index b8dec3df..ae1a93b1 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
@@ -129,7 +129,7 @@
   if (any_in_record_member_value.IsEmpty() || any_in_record_member_value->IsUndefined()) {
     // Do nothing.
   } else {
-    Vector<std::pair<String, ScriptValue>> any_in_record_member_cpp_value = NativeValueTraits<IDLRecord<IDLString, ScriptValue>>::NativeValue(isolate, any_in_record_member_value, exception_state);
+    HeapVector<std::pair<String, ScriptValue>> any_in_record_member_cpp_value = NativeValueTraits<IDLRecord<IDLString, ScriptValue>>::NativeValue(isolate, any_in_record_member_value, exception_state);
     if (exception_state.HadException())
       return;
     impl->setAnyInRecordMember(any_in_record_member_cpp_value);
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
index 3aab30c..bd9cbc8e 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
@@ -7225,7 +7225,7 @@
   TestObject* impl = V8TestObject::ToImpl(info.Holder());
 
   int32_t long_arg;
-  Vector<ScriptValue> rest_args;
+  HeapVector<ScriptValue> rest_args;
   long_arg = NativeValueTraits<IDLLong>::NativeValue(info.GetIsolate(), info[0], exception_state);
   if (exception_state.HadException())
     return;
@@ -7243,7 +7243,7 @@
   TestObject* impl = V8TestObject::ToImpl(info.Holder());
 
   V8StringResource<> string_arg;
-  Vector<ScriptValue> rest_args;
+  HeapVector<ScriptValue> rest_args;
   string_arg = info[0];
   if (!string_arg.Prepare())
     return;
diff --git a/third_party/blink/renderer/controller/blink_leak_detector.cc b/third_party/blink/renderer/controller/blink_leak_detector.cc
index 16d7fdf..d35880b 100644
--- a/third_party/blink/renderer/controller/blink_leak_detector.cc
+++ b/third_party/blink/renderer/controller/blink_leak_detector.cc
@@ -127,8 +127,6 @@
   result->number_of_live_context_lifecycle_state_observers =
       InstanceCounters::CounterValue(
           InstanceCounters::kContextLifecycleStateObserverCounter);
-  result->number_of_live_script_promises =
-      InstanceCounters::CounterValue(InstanceCounters::kScriptPromiseCounter);
   result->number_of_live_frames =
       InstanceCounters::CounterValue(InstanceCounters::kFrameCounter);
   result->number_of_live_v8_per_context_data = InstanceCounters::CounterValue(
diff --git a/third_party/blink/renderer/core/animation/BUILD.gn b/third_party/blink/renderer/core/animation/BUILD.gn
index d1530f95..a048dcf 100644
--- a/third_party/blink/renderer/core/animation/BUILD.gn
+++ b/third_party/blink/renderer/core/animation/BUILD.gn
@@ -282,7 +282,6 @@
     "document_timeline_test.cc",
     "effect_input_test.cc",
     "effect_stack_test.cc",
-    "interpolable_length_test.cc",
     "interpolable_value_test.cc",
     "interpolation_effect_test.cc",
     "keyframe_effect_model_test.cc",
diff --git a/third_party/blink/renderer/core/animation/animation_time_delta.h b/third_party/blink/renderer/core/animation/animation_time_delta.h
index 157fda2..b1af4e69 100644
--- a/third_party/blink/renderer/core/animation/animation_time_delta.h
+++ b/third_party/blink/renderer/core/animation/animation_time_delta.h
@@ -6,6 +6,11 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIME_DELTA_H_
 
 #include "third_party/blink/renderer/core/animation/buildflags.h"
+
+#if BUILDFLAG(BLINK_ANIMATION_USE_TIME_DELTA)
+#include "base/time/time.h"
+#endif
+
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
diff --git a/third_party/blink/renderer/core/animation/effect_input_test.cc b/third_party/blink/renderer/core/animation/effect_input_test.cc
index 3ca4bd2..bdfac8f9 100644
--- a/third_party/blink/renderer/core/animation/effect_input_test.cc
+++ b/third_party/blink/renderer/core/animation/effect_input_test.cc
@@ -28,14 +28,14 @@
   V8TestingScope scope;
   ScriptState* script_state = scope.GetScriptState();
 
-  Vector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
-                                             .AddString("width", "100px")
-                                             .AddString("offset", "0")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("width", "0px")
-                                             .AddString("offset", "1")
-                                             .GetScriptValue()};
+  HeapVector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
+                                                 .AddString("width", "100px")
+                                                 .AddString("offset", "0")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("width", "0px")
+                                                 .AddString("offset", "1")
+                                                 .GetScriptValue()};
 
   ScriptValue js_keyframes(
       script_state,
@@ -53,14 +53,14 @@
   V8TestingScope scope;
   ScriptState* script_state = scope.GetScriptState();
 
-  Vector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
-                                             .AddString("width", "0px")
-                                             .AddString("offset", "1")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("width", "100px")
-                                             .AddString("offset", "0")
-                                             .GetScriptValue()};
+  HeapVector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
+                                                 .AddString("width", "0px")
+                                                 .AddString("offset", "1")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("width", "100px")
+                                                 .AddString("offset", "0")
+                                                 .GetScriptValue()};
 
   ScriptValue js_keyframes(
       script_state,
@@ -78,17 +78,17 @@
   V8TestingScope scope;
   ScriptState* script_state = scope.GetScriptState();
 
-  Vector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
-                                             .AddString("width", "100px")
-                                             .AddString("offset", "0")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("width", "200px")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("width", "0px")
-                                             .AddString("offset", "1")
-                                             .GetScriptValue()};
+  HeapVector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
+                                                 .AddString("width", "100px")
+                                                 .AddString("offset", "0")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("width", "200px")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("width", "0px")
+                                                 .AddString("offset", "1")
+                                                 .GetScriptValue()};
 
   ScriptValue js_keyframes(
       script_state,
@@ -106,21 +106,21 @@
   V8TestingScope scope;
   ScriptState* script_state = scope.GetScriptState();
 
-  Vector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
-                                             .AddString("height", "100px")
-                                             .AddString("offset", "0.5")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("height", "150px")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("height", "200px")
-                                             .AddString("offset", "0")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("height", "300px")
-                                             .AddString("offset", "1")
-                                             .GetScriptValue()};
+  HeapVector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
+                                                 .AddString("height", "100px")
+                                                 .AddString("offset", "0.5")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("height", "150px")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("height", "200px")
+                                                 .AddString("offset", "0")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("height", "300px")
+                                                 .AddString("offset", "1")
+                                                 .GetScriptValue()};
 
   ScriptValue js_keyframes(
       script_state,
@@ -137,17 +137,17 @@
   ScriptState* script_state = scope.GetScriptState();
 
   // Not loosely sorted by offset, and there exists a keyframe with null offset.
-  Vector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
-                                             .AddString("width", "0px")
-                                             .AddString("offset", "1")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("width", "200px")
-                                             .GetScriptValue(),
-                                         V8ObjectBuilder(script_state)
-                                             .AddString("width", "200px")
-                                             .AddString("offset", "0")
-                                             .GetScriptValue()};
+  HeapVector<ScriptValue> blink_keyframes = {V8ObjectBuilder(script_state)
+                                                 .AddString("width", "0px")
+                                                 .AddString("offset", "1")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("width", "200px")
+                                                 .GetScriptValue(),
+                                             V8ObjectBuilder(script_state)
+                                                 .AddString("width", "200px")
+                                                 .AddString("offset", "0")
+                                                 .GetScriptValue()};
 
   ScriptValue js_keyframes(
       script_state,
diff --git a/third_party/blink/renderer/core/animation/interpolable_length.cc b/third_party/blink/renderer/core/animation/interpolable_length.cc
index 006a040..9f6a511 100644
--- a/third_party/blink/renderer/core/animation/interpolable_length.cc
+++ b/third_party/blink/renderer/core/animation/interpolable_length.cc
@@ -14,37 +14,27 @@
 
 namespace blink {
 
-using UnitType = CSSPrimitiveValue::UnitType;
-
-namespace {
-
-CSSMathExpressionNode* NumberNode(double number) {
-  return CSSMathExpressionNumericLiteral::Create(
-      CSSNumericLiteralValue::Create(number, UnitType::kNumber));
-}
-
-CSSMathExpressionNode* PercentageNode(double number) {
-  return CSSMathExpressionNumericLiteral::Create(
-      CSSNumericLiteralValue::Create(number, UnitType::kPercentage));
-}
-
-}  // namespace
-
 // static
 std::unique_ptr<InterpolableLength> InterpolableLength::CreatePixels(
     double pixels) {
-  return std::make_unique<InterpolableLength>(pixels, UnitType::kPixels);
+  CSSLengthArray length_array;
+  length_array.values[CSSPrimitiveValue::kUnitTypePixels] = pixels;
+  length_array.type_flags.set(CSSPrimitiveValue::kUnitTypePixels);
+  return std::make_unique<InterpolableLength>(std::move(length_array));
 }
 
 // static
 std::unique_ptr<InterpolableLength> InterpolableLength::CreatePercent(
     double percent) {
-  return std::make_unique<InterpolableLength>(percent, UnitType::kPercentage);
+  CSSLengthArray length_array;
+  length_array.values[CSSPrimitiveValue::kUnitTypePercentage] = percent;
+  length_array.type_flags.set(CSSPrimitiveValue::kUnitTypePercentage);
+  return std::make_unique<InterpolableLength>(std::move(length_array));
 }
 
 // static
 std::unique_ptr<InterpolableLength> InterpolableLength::CreateNeutral() {
-  return std::make_unique<InterpolableLength>();
+  return std::make_unique<InterpolableLength>(CSSLengthArray());
 }
 
 // static
@@ -58,13 +48,14 @@
       !primitive_value->IsCalculatedPercentageWithLength())
     return nullptr;
 
-  if (const auto* numeric_literal =
-          DynamicTo<CSSNumericLiteralValue>(primitive_value)) {
-    return std::make_unique<InterpolableLength>(*numeric_literal);
+  CSSLengthArray length_array;
+  if (!primitive_value->AccumulateLengthArray(length_array)) {
+    // TODO(crbug.com/991672): Implement interpolation when CSS comparison
+    // functions min/max are involved.
+    return nullptr;
   }
 
-  return std::make_unique<InterpolableLength>(
-      *To<CSSMathFunctionValue>(primitive_value)->ExpressionNode());
+  return std::make_unique<InterpolableLength>(std::move(length_array));
 }
 
 // static
@@ -74,16 +65,24 @@
   if (!length.IsSpecified())
     return nullptr;
 
-  // Do not use CSSPrimitiveValue::CreateFromLength(), as it might drop 0% in
-  // calculated lengths.
-  // TODO(crbug.com/991672): Try not to drop 0% there.
+  if (length.IsCalculated() && length.GetCalculationValue().IsExpression()) {
+    // TODO(crbug.com/991672): Support interpolation on min/max results.
+    return nullptr;
+  }
 
-  if (length.IsFixed())
-    return CreatePixels(length.Pixels() / zoom);
-  if (length.IsPercent())
-    return CreatePercent(length.Percent());
-  return std::make_unique<InterpolableLength>(
-      *CSSMathExpressionNode::Create(length.GetCalculationValue()));
+  PixelsAndPercent pixels_and_percent = length.GetPixelsAndPercent();
+  CSSLengthArray length_array;
+
+  length_array.values[CSSPrimitiveValue::kUnitTypePixels] =
+      pixels_and_percent.pixels / zoom;
+  length_array.type_flags[CSSPrimitiveValue::kUnitTypePixels] =
+      pixels_and_percent.pixels != 0;
+
+  length_array.values[CSSPrimitiveValue::kUnitTypePercentage] =
+      pixels_and_percent.percent;
+  length_array.type_flags[CSSPrimitiveValue::kUnitTypePercentage] =
+      length.IsPercentOrCalc();
+  return std::make_unique<InterpolableLength>(std::move(length_array));
 }
 
 // static
@@ -95,168 +94,107 @@
   // should stop doing that.
   auto& start_length = To<InterpolableLength>(*start);
   auto& end_length = To<InterpolableLength>(*end);
-  if (start_length.HasPercentage() || end_length.HasPercentage()) {
-    start_length.SetHasPercentage();
-    end_length.SetHasPercentage();
-  }
+  start_length.length_array_.type_flags |= end_length.length_array_.type_flags;
+  end_length.length_array_.type_flags = start_length.length_array_.type_flags;
   return PairwiseInterpolationValue(std::move(start), std::move(end));
 }
 
-InterpolableLength::InterpolableLength(double value, UnitType unit_type) {
-  SetNumericLiteral(value, unit_type);
-}
-
-InterpolableLength::InterpolableLength()
-    : InterpolableLength(0, UnitType::kPixels) {}
-
-InterpolableLength::InterpolableLength(const CSSNumericLiteralValue& value)
-    : InterpolableLength(value.DoubleValue(), value.GetType()) {}
-
-InterpolableLength::InterpolableLength(
-    const CSSMathExpressionNode& expression) {
-  SetExpression(expression);
-}
-
-std::unique_ptr<InterpolableValue> InterpolableLength::Clone() const {
-  return std::make_unique<InterpolableLength>(*this);
-}
-
-void InterpolableLength::SetNumericLiteral(
-    double value,
-    CSSPrimitiveValue::UnitType unit_type) {
-  type_ = Type::kNumericLiteral;
-  single_value_ = value;
-  unit_type_ = unit_type;
-  expression_.Clear();
-}
-
-void InterpolableLength::SetNumericLiteral(
-    const CSSNumericLiteralValue& value) {
-  SetNumericLiteral(value.DoubleValue(), value.GetType());
-}
-
-void InterpolableLength::SetExpression(
-    const CSSMathExpressionNode& expression) {
-  if (expression.IsNumericLiteral()) {
-    return SetNumericLiteral(
-        *To<CSSMathExpressionNumericLiteral>(expression).GetValue());
-  }
-
-  type_ = Type::kExpression;
-  expression_ = &expression;
-}
-
-const CSSMathExpressionNode& InterpolableLength::AsExpression() const {
-  if (IsExpression())
-    return *expression_;
-  return *CSSMathExpressionNumericLiteral::Create(
-      CSSNumericLiteralValue::Create(single_value_, unit_type_));
-}
-
-bool InterpolableLength::HasPercentage() const {
-  if (IsNumericLiteral())
-    return unit_type_ == UnitType::kPercentage;
-  return expression_->HasPercentage();
-}
-
-void InterpolableLength::SetHasPercentage() {
-  DEFINE_STATIC_LOCAL(Persistent<CSSMathExpressionNode>, zero_percent,
-                      {PercentageNode(0)});
-  if (HasPercentage())
-    return;
-  if (IsZeroLength())
-    return SetNumericLiteral(0, UnitType::kPercentage);
-  SetExpression(*CSSMathExpressionBinaryOperation::Create(
-      &AsExpression(), zero_percent, CSSMathOperator::kAdd));
-}
-
 void InterpolableLength::SubtractFromOneHundredPercent() {
-  DEFINE_STATIC_LOCAL(Persistent<CSSMathExpressionNode>, hundred_percent,
-                      {PercentageNode(100)});
-  if (IsNumericLiteral()) {
-    if (unit_type_ == UnitType::kPercentage) {
-      single_value_ = 100 - single_value_;
-      return;
-    }
-    if (IsZeroLength())
-      return SetNumericLiteral(100, UnitType::kPercentage);
-
-    // Fall through, as the result requires an expression to represent
-  }
-
-  SetExpression(*CSSMathExpressionBinaryOperation::CreateSimplified(
-      hundred_percent, &AsExpression(), CSSMathOperator::kSubtract));
+  for (double& value : length_array_.values)
+    value *= -1;
+  length_array_.values[CSSPrimitiveValue::kUnitTypePercentage] += 100;
+  length_array_.type_flags.set(CSSPrimitiveValue::kUnitTypePercentage);
 }
 
 static double ClampToRange(double x, ValueRange range) {
   return (range == kValueRangeNonNegative && x < 0) ? 0 : x;
 }
 
+static CSSPrimitiveValue::UnitType IndexToUnitType(wtf_size_t index) {
+  return CSSPrimitiveValue::LengthUnitTypeToUnitType(
+      static_cast<CSSPrimitiveValue::LengthUnitType>(index));
+}
+
 Length InterpolableLength::CreateLength(
     const CSSToLengthConversionData& conversion_data,
     ValueRange range) const {
-  if (IsNumericLiteral()) {
-    const double value = ClampToRange(single_value_, range);
-    if (CSSPrimitiveValue::IsLength(unit_type_)) {
-      const double value_px =
-          conversion_data.ZoomedComputedPixels(value, unit_type_);
-      return Length::Fixed(CSSPrimitiveValue::ClampToCSSLengthRange(value_px));
+  bool has_percentage = HasPercentage();
+  double pixels = 0;
+  double percentage = 0;
+  for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
+    double value = length_array_.values[i];
+    if (value == 0)
+      continue;
+    if (i == CSSPrimitiveValue::kUnitTypePercentage) {
+      percentage = value;
+    } else {
+      pixels += conversion_data.ZoomedComputedPixels(value, IndexToUnitType(i));
     }
-    DCHECK_EQ(UnitType::kPercentage, unit_type_);
-    return Length::Percent(value);
   }
 
-  // In the uncommon case where |this| is a math expression, this implementation
-  // avoids a lot of code complexity at the cost of creating a temporary
-  // |CSSMathFunctionValue| object.
-  return CreateCSSValue(range)->ConvertToLength(conversion_data);
+  if (percentage != 0)
+    has_percentage = true;
+  if (pixels != 0 && has_percentage) {
+    return Length(CalculationValue::Create(
+        PixelsAndPercent(clampTo<float>(pixels), clampTo<float>(percentage)),
+        range));
+  }
+  if (has_percentage)
+    return Length::Percent(ClampToRange(percentage, range));
+  return Length::Fixed(
+      CSSPrimitiveValue::ClampToCSSLengthRange(ClampToRange(pixels, range)));
 }
 
 const CSSPrimitiveValue* InterpolableLength::CreateCSSValue(
     ValueRange range) const {
-  if (IsExpression())
-    return CSSMathFunctionValue::Create(&AsExpression(), range);
+  bool has_percentage = HasPercentage();
 
-  DCHECK(IsNumericLiteral());
-  return CSSNumericLiteralValue::Create(ClampToRange(single_value_, range),
-                                        unit_type_);
-}
+  CSSMathExpressionNode* root_node = nullptr;
+  CSSNumericLiteralValue* first_value = nullptr;
 
-void InterpolableLength::Scale(double scale) {
-  if (IsNumericLiteral()) {
-    single_value_ *= scale;
-    return;
+  for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
+    double value = length_array_.values[i];
+    if (value == 0 &&
+        (i != CSSPrimitiveValue::kUnitTypePercentage || !has_percentage)) {
+      continue;
+    }
+    CSSNumericLiteralValue* current_value =
+        CSSNumericLiteralValue::Create(value, IndexToUnitType(i));
+
+    if (!first_value) {
+      DCHECK(!root_node);
+      first_value = current_value;
+      continue;
+    }
+    CSSMathExpressionNode* current_node =
+        CSSMathExpressionNumericLiteral::Create(current_value);
+    if (!root_node) {
+      root_node = CSSMathExpressionNumericLiteral::Create(first_value);
+    }
+    root_node = CSSMathExpressionBinaryOperation::Create(
+        root_node, current_node, CSSMathOperator::kAdd);
   }
 
-  DCHECK(IsExpression());
-  SetExpression(*CSSMathExpressionBinaryOperation::CreateSimplified(
-      &AsExpression(), NumberNode(scale), CSSMathOperator::kMultiply));
+  if (root_node) {
+    return CSSMathFunctionValue::Create(root_node, range);
+  }
+  if (first_value) {
+    if (range == kValueRangeNonNegative && first_value->DoubleValue() < 0)
+      return CSSNumericLiteralValue::Create(0, first_value->GetType());
+    return first_value;
+  }
+  return CSSNumericLiteralValue::Create(0,
+                                        CSSPrimitiveValue::UnitType::kPixels);
 }
 
 void InterpolableLength::ScaleAndAdd(double scale,
                                      const InterpolableValue& other) {
   const InterpolableLength& other_length = To<InterpolableLength>(other);
-  if (IsNumericLiteral() && other_length.IsNumericLiteral() &&
-      unit_type_ == other_length.unit_type_) {
-    single_value_ = single_value_ * scale + other_length.single_value_;
-    return;
+  for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
+    length_array_.values[i] =
+        length_array_.values[i] * scale + other_length.length_array_.values[i];
   }
-
-  // Avoid creating an addition expression with a zero-length operand.
-  if (IsZeroLength()) {
-    *this = other_length;
-    return;
-  }
-  if (other_length.IsZeroLength())
-    return Scale(scale);
-
-  CSSMathExpressionNode* scaled =
-      CSSMathExpressionBinaryOperation::CreateSimplified(
-          &AsExpression(), NumberNode(scale), CSSMathOperator::kMultiply);
-  CSSMathExpressionNode* result =
-      CSSMathExpressionBinaryOperation::CreateSimplified(
-          scaled, &other_length.AsExpression(), CSSMathOperator::kAdd);
-  SetExpression(*result);
+  length_array_.type_flags |= other_length.length_array_.type_flags;
 }
 
 void InterpolableLength::AssertCanInterpolateWith(
@@ -266,47 +204,23 @@
   // two |InterpolableLength| objects should also assign them the same shape
   // (i.e. type flags) after merging into a |PairwiseInterpolationValue|. We
   // currently fail to do that, and hit the following DCHECK:
-  // DCHECK_EQ(HasPercentage(),
-  //           To<InterpolableLength>(other).HasPercentage());
+  // DCHECK_EQ(length_array_.type_flags,
+  //           To<InterpolableLength>(other).length_array_.type_flags);
 }
 
 void InterpolableLength::Interpolate(const InterpolableValue& to,
                                      const double progress,
                                      InterpolableValue& result) const {
-  const auto& to_length = To<InterpolableLength>(to);
-  auto& result_length = To<InterpolableLength>(result);
-
-  if (IsNumericLiteral() && to_length.IsNumericLiteral() &&
-      unit_type_ == to_length.unit_type_) {
-    return result_length.SetNumericLiteral(
-        Blend(single_value_, to_length.single_value_, progress), unit_type_);
+  const CSSLengthArray& to_length_array =
+      To<InterpolableLength>(to).length_array_;
+  CSSLengthArray& result_length_array =
+      To<InterpolableLength>(result).length_array_;
+  for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
+    result_length_array.values[i] =
+        Blend(length_array_.values[i], to_length_array.values[i], progress);
   }
-
-  // Avoid creating an addition expression with a zero-length operand.
-  if (IsZeroLength()) {
-    result_length = to_length;
-    return result_length.Scale(progress);
-  }
-  if (to_length.IsZeroLength()) {
-    result_length = *this;
-    return result_length.Scale(1 - progress);
-  }
-
-  CSSMathExpressionNode* blended_from =
-      CSSMathExpressionBinaryOperation::CreateSimplified(
-          &AsExpression(), NumberNode(1 - progress),
-          CSSMathOperator::kMultiply);
-  CSSMathExpressionNode* blended_to =
-      CSSMathExpressionBinaryOperation::CreateSimplified(
-          &to_length.AsExpression(), NumberNode(progress),
-          CSSMathOperator::kMultiply);
-  CSSMathExpressionNode* result_expression =
-      CSSMathExpressionBinaryOperation::CreateSimplified(
-          blended_from, blended_to, CSSMathOperator::kAdd);
-  result_length.SetExpression(*result_expression);
-
-  DCHECK_EQ(result_length.HasPercentage(),
-            HasPercentage() || to_length.HasPercentage());
+  result_length_array.type_flags =
+      length_array_.type_flags | to_length_array.type_flags;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/interpolable_length.h b/third_party/blink/renderer/core/animation/interpolable_length.h
index 37e7ac5..bd06bcf 100644
--- a/third_party/blink/renderer/core/animation/interpolable_length.h
+++ b/third_party/blink/renderer/core/animation/interpolable_length.h
@@ -10,24 +10,19 @@
 #include "third_party/blink/renderer/core/animation/pairwise_interpolation_value.h"
 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
 #include "third_party/blink/renderer/platform/geometry/length.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
 class CSSToLengthConversionData;
-class CSSMathExpressionNode;
-class CSSNumericLiteralValue;
-class CSSValue;
 
 class CORE_EXPORT InterpolableLength final : public InterpolableValue {
  public:
   ~InterpolableLength() final {}
-
-  InterpolableLength();
-  InterpolableLength(double value, CSSPrimitiveValue::UnitType);
-  explicit InterpolableLength(const CSSNumericLiteralValue& value);
-  explicit InterpolableLength(const CSSMathExpressionNode& expression);
+  InterpolableLength(const CSSLengthArray& length_array)
+      : length_array_(length_array) {}
+  InterpolableLength(CSSLengthArray&& length_array)
+      : length_array_(std::move(length_array)) {}
 
   static std::unique_ptr<InterpolableLength> CreatePixels(double pixels);
   static std::unique_ptr<InterpolableLength> CreatePercent(double pixels);
@@ -50,9 +45,10 @@
   // expressions.
   const CSSPrimitiveValue* CreateCSSValue(ValueRange range) const;
 
-  // Mix the length with the percentage type, if it's not mixed already
-  void SetHasPercentage();
-  bool HasPercentage() const;
+  bool HasPercentage() const {
+    return length_array_.type_flags.test(
+        CSSPrimitiveValue::kUnitTypePercentage);
+  }
   void SubtractFromOneHundredPercent();
 
   // InterpolableValue:
@@ -61,44 +57,27 @@
     NOTREACHED();
     return false;
   }
-  std::unique_ptr<InterpolableValue> Clone() const final;
-  std::unique_ptr<InterpolableValue> CloneAndZero() const final {
-    return std::make_unique<InterpolableLength>();
+  std::unique_ptr<InterpolableValue> Clone() const final {
+    return std::make_unique<InterpolableLength>(length_array_);
   }
-  void Scale(double scale) final;
+  std::unique_ptr<InterpolableValue> CloneAndZero() const final {
+    return std::make_unique<InterpolableLength>(CSSLengthArray());
+  }
+  void Scale(double scale) final {
+    for (double& value : length_array_.values) {
+      value *= scale;
+    }
+  }
   void ScaleAndAdd(double scale, const InterpolableValue& other) final;
   void AssertCanInterpolateWith(const InterpolableValue& other) const final;
 
  private:
-  friend class InterpolableLengthTest;
-
   // InterpolableValue:
   void Interpolate(const InterpolableValue& to,
                    const double progress,
                    InterpolableValue& result) const final;
 
-  bool IsNumericLiteral() const { return type_ == Type::kNumericLiteral; }
-  bool IsExpression() const { return type_ == Type::kExpression; }
-
-  bool IsZeroLength() const {
-    return IsNumericLiteral() && CSSPrimitiveValue::IsLength(unit_type_) &&
-           single_value_ == 0;
-  }
-
-  void SetNumericLiteral(double value, CSSPrimitiveValue::UnitType unit_type);
-  void SetNumericLiteral(const CSSNumericLiteralValue& value);
-  void SetExpression(const CSSMathExpressionNode& expression);
-  const CSSMathExpressionNode& AsExpression() const;
-
-  enum class Type { kNumericLiteral, kExpression };
-  Type type_;
-
-  // Set when |type_| is |kNumericLiteral|.
-  double single_value_;
-  CSSPrimitiveValue::UnitType unit_type_;
-
-  // Non-null when |type_| is |kExpression|.
-  Persistent<const CSSMathExpressionNode> expression_;
+  CSSLengthArray length_array_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/animation/interpolable_length_test.cc b/third_party/blink/renderer/core/animation/interpolable_length_test.cc
deleted file mode 100644
index 08562ba4..0000000
--- a/third_party/blink/renderer/core/animation/interpolable_length_test.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/animation/interpolable_length.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-using UnitType = CSSPrimitiveValue::UnitType;
-
-// Verifies the "shape" of the |InterpolableLength| after various operations.
-// Subject to change if the internal representation of |InterpolableLength| is
-// changed.
-class InterpolableLengthTest : public ::testing::Test {
- protected:
-  std::unique_ptr<InterpolableLength> Create(double value,
-                                             UnitType type) const {
-    return std::make_unique<InterpolableLength>(value, type);
-  }
-
-  std::unique_ptr<InterpolableLength> Interpolate(
-      const InterpolableLength& from,
-      const InterpolableLength& to,
-      double progress) {
-    std::unique_ptr<InterpolableLength> result =
-        InterpolableLength::CreateNeutral();
-    from.Interpolate(to, progress, *result);
-    return result;
-  }
-
-  bool IsNumericLiteral(const InterpolableLength& length) const {
-    return length.IsNumericLiteral();
-  }
-
-  double GetSingleValue(const InterpolableLength& length) const {
-    DCHECK(length.IsNumericLiteral());
-    return length.single_value_;
-  }
-
-  UnitType GetUnitType(const InterpolableLength& length) const {
-    DCHECK(length.IsNumericLiteral());
-    return length.unit_type_;
-  }
-
-  bool IsExpression(const InterpolableLength& length) const {
-    return length.IsExpression();
-  }
-};
-
-TEST_F(InterpolableLengthTest, InterpolateSameUnits) {
-  {
-    auto length_a = InterpolableLength::CreatePixels(4);
-    auto length_b = InterpolableLength::CreatePixels(6);
-    auto result = Interpolate(*length_a, *length_b, 0.5);
-
-    EXPECT_TRUE(IsNumericLiteral(*result));
-    EXPECT_EQ(5, GetSingleValue(*result));
-    EXPECT_EQ(UnitType::kPixels, GetUnitType(*result));
-    EXPECT_FALSE(result->HasPercentage());
-  }
-
-  {
-    auto length_a = Create(4, UnitType::kEms);
-    auto length_b = Create(6, UnitType::kEms);
-    auto result = Interpolate(*length_a, *length_b, 0.5);
-
-    EXPECT_TRUE(IsNumericLiteral(*result));
-    EXPECT_EQ(5, GetSingleValue(*result));
-    EXPECT_EQ(UnitType::kEms, GetUnitType(*result));
-    EXPECT_FALSE(result->HasPercentage());
-  }
-
-  {
-    auto length_a = InterpolableLength::CreatePercent(4);
-    auto length_b = InterpolableLength::CreatePercent(6);
-    auto result = Interpolate(*length_a, *length_b, 0.5);
-
-    EXPECT_TRUE(IsNumericLiteral(*result));
-    EXPECT_EQ(5, GetSingleValue(*result));
-    EXPECT_EQ(UnitType::kPercentage, GetUnitType(*result));
-    EXPECT_TRUE(result->HasPercentage());
-  }
-}
-
-TEST_F(InterpolableLengthTest, InterpolateIncompatibleUnits) {
-  {
-    auto length_a = InterpolableLength::CreatePixels(4);
-    auto length_b = Create(6, UnitType::kEms);
-    auto result = Interpolate(*length_a, *length_b, 0.5);
-
-    EXPECT_TRUE(IsExpression(*result));
-    EXPECT_FALSE(result->HasPercentage());
-    EXPECT_EQ("calc(2px + 3em)",
-              result->CreateCSSValue(kValueRangeAll)->CustomCSSText());
-  }
-}
-
-TEST_F(InterpolableLengthTest, SetHasPercentage) {
-  {
-    auto length = InterpolableLength::CreateNeutral();
-    length->SetHasPercentage();
-
-    EXPECT_TRUE(length->HasPercentage());
-    EXPECT_TRUE(IsNumericLiteral(*length));
-    EXPECT_EQ(0, GetSingleValue(*length));
-    EXPECT_EQ(UnitType::kPercentage, GetUnitType(*length));
-  }
-
-  {
-    auto length = InterpolableLength::CreatePercent(10);
-    length->SetHasPercentage();
-
-    EXPECT_TRUE(length->HasPercentage());
-    EXPECT_TRUE(IsNumericLiteral(*length));
-    EXPECT_EQ(10, GetSingleValue(*length));
-    EXPECT_EQ(UnitType::kPercentage, GetUnitType(*length));
-  }
-
-  {
-    auto length = InterpolableLength::CreatePixels(10);
-    length->SetHasPercentage();
-
-    EXPECT_TRUE(length->HasPercentage());
-    EXPECT_TRUE(IsExpression(*length));
-    EXPECT_EQ("calc(10px + 0%)",
-              length->CreateCSSValue(kValueRangeAll)->CustomCSSText());
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.cc b/third_party/blink/renderer/core/animation/keyframe_effect.cc
index dbfe7b4..4b4150c 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -142,8 +142,9 @@
       EffectModel::StringToCompositeOperation(composite_string).value());
 }
 
-Vector<ScriptValue> KeyframeEffect::getKeyframes(ScriptState* script_state) {
-  Vector<ScriptValue> computed_keyframes;
+HeapVector<ScriptValue> KeyframeEffect::getKeyframes(
+    ScriptState* script_state) {
+  HeapVector<ScriptValue> computed_keyframes;
   if (!model_->HasFrames())
     return computed_keyframes;
 
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.h b/third_party/blink/renderer/core/animation/keyframe_effect.h
index 5d43efc2..f70caded 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect.h
+++ b/third_party/blink/renderer/core/animation/keyframe_effect.h
@@ -81,7 +81,7 @@
   void setTarget(Element*);
   String composite() const;
   void setComposite(String);
-  Vector<ScriptValue> getKeyframes(ScriptState*);
+  HeapVector<ScriptValue> getKeyframes(ScriptState*);
   void setKeyframes(ScriptState*,
                     const ScriptValue& keyframes,
                     ExceptionState&);
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
index fbefcf7..7ee89a1 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
@@ -110,7 +110,7 @@
   ScriptState* script_state = scope.GetScriptState();
   NonThrowableExceptionState exception_state;
 
-  Vector<ScriptValue> blink_keyframes = {
+  HeapVector<ScriptValue> blink_keyframes = {
       V8ObjectBuilder(script_state)
           .AddString("width", "100px")
           .AddString("offset", "0")
@@ -196,7 +196,7 @@
                                   effect_options_dictionary, exception_state);
   EXPECT_FALSE(exception_state.HadException());
 
-  Vector<ScriptValue> blink_keyframes = {
+  HeapVector<ScriptValue> blink_keyframes = {
       V8ObjectBuilder(script_state)
           .AddString("width", "100px")
           .AddString("composite", "replace")
@@ -349,7 +349,7 @@
 
   // But if we then setKeyframes with CSS-targeting keyframes, the composite
   // should fallback to 'replace'.
-  Vector<ScriptValue> blink_keyframes = {
+  HeapVector<ScriptValue> blink_keyframes = {
       V8ObjectBuilder(script_state).AddString("width", "10px").GetScriptValue(),
       V8ObjectBuilder(script_state).AddString("width", "0px").GetScriptValue()};
   ScriptValue new_js_keyframes(
diff --git a/third_party/blink/renderer/core/css/css_math_expression_node.h b/third_party/blink/renderer/core/css/css_math_expression_node.h
index 2301e235..a22e4ac4 100644
--- a/third_party/blink/renderer/core/css/css_math_expression_node.h
+++ b/third_party/blink/renderer/core/css/css_math_expression_node.h
@@ -114,11 +114,6 @@
   virtual bool IsComputationallyIndependent() const = 0;
 
   CalculationCategory Category() const { return category_; }
-  bool HasPercentage() const {
-    return category_ == kCalcPercent || category_ == kCalcPercentNumber ||
-           category_ == kCalcPercentLength ||
-           category_ == kCalcPercentLengthNumber;
-  }
 
   // Returns the unit type of the math expression *without doing any type
   // conversion* (e.g., 1px + 1em needs type conversion to resolve).
@@ -164,7 +159,6 @@
                                   bool is_integer);
 
   bool IsNumericLiteral() const final { return true; }
-  const CSSNumericLiteralValue* GetValue() const { return value_; }
 
   bool IsZero() const final;
   String CustomCSSText() const final;
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
index 98a8b47c..552f495 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -305,7 +305,7 @@
     // See https://drafts.csswg.org/css-display/#unbox-html
     // Some of these elements are handled with other adjustments above.
     if (IsA<HTMLBRElement>(element) || IsHTMLWBRElement(element) ||
-        IsHTMLMeterElement(element) || IsHTMLProgressElement(element) ||
+        IsA<HTMLMeterElement>(element) || IsHTMLProgressElement(element) ||
         IsA<HTMLCanvasElement>(element) || IsHTMLMediaElement(element) ||
         IsHTMLInputElement(element) || IsHTMLTextAreaElement(element) ||
         IsHTMLSelectElement(element)) {
diff --git a/third_party/blink/renderer/core/dom/document_statistics_collector.cc b/third_party/blink/renderer/core/dom/document_statistics_collector.cc
index c7675d1..12538a2 100644
--- a/third_party/blink/renderer/core/dom/document_statistics_collector.cc
+++ b/third_party/blink/renderer/core/dom/document_statistics_collector.cc
@@ -164,13 +164,13 @@
   DEFINE_STATIC_LOCAL(AtomicString, property_attr, ("property"));
   for (const Element* child = ElementTraversal::FirstChild(head); child;
        child = ElementTraversal::NextSibling(*child)) {
-    if (!IsHTMLMetaElement(*child))
+    auto* meta = DynamicTo<HTMLMetaElement>(child);
+    if (!meta)
       continue;
-    const HTMLMetaElement& meta = ToHTMLMetaElement(*child);
 
-    if (meta.GetName() == og_type ||
-        meta.getAttribute(property_attr) == og_type) {
-      if (DeprecatedEqualIgnoringCase(meta.Content(), "article")) {
+    if (meta->GetName() == og_type ||
+        meta->getAttribute(property_attr) == og_type) {
+      if (DeprecatedEqualIgnoringCase(meta->Content(), "article")) {
         return true;
       }
     }
diff --git a/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc b/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
index 6632afef..141e536d 100644
--- a/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
@@ -230,7 +230,7 @@
   for (wtf_size_t i = ancestors.size(); i != 0; --i) {
     Element& cloned_child = ancestors[i - 1]->CloneWithoutChildren();
     // Preserve list item numbering in cloned lists.
-    if (IsHTMLOListElement(cloned_child)) {
+    if (IsA<HTMLOListElement>(cloned_child)) {
       Node* list_child_node = i > 1 ? ancestors[i - 2].Get() : start_node;
       // The first child of the cloned list might not be a list item element,
       // find the first one so that we know where to start numbering.
diff --git a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
index c63bfb9..4bd70fd 100644
--- a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
@@ -1661,7 +1661,7 @@
   // FIXME: Can't we do something better when the immediate parent wasn't a list
   // node?
   if (!list_node ||
-      (!IsHTMLUListElement(*list_node) && !IsHTMLOListElement(*list_node)) ||
+      (!IsHTMLUListElement(*list_node) && !IsA<HTMLOListElement>(*list_node)) ||
       !HasEditableStyle(*list_node) ||
       list_node == RootEditableElement(*empty_list_item))
     return false;
@@ -1695,7 +1695,7 @@
       }
       // If listNode does NOT appear at the end of the outer list item, then
       // behave as if in a regular paragraph.
-    } else if (IsHTMLOListElement(*block_enclosing_list) ||
+    } else if (IsA<HTMLOListElement>(*block_enclosing_list) ||
                IsHTMLUListElement(*block_enclosing_list)) {
       new_block = MakeGarbageCollected<HTMLLIElement>(GetDocument());
     }
diff --git a/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc b/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
index 574fa2d..f900701 100644
--- a/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
+++ b/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
@@ -366,7 +366,7 @@
   ContainerNode* root = HighestEditableRoot(FirstPositionInOrBeforeNode(*node));
 
   for (Node& runner : NodeTraversal::AncestorsOf(*node)) {
-    if (IsHTMLUListElement(runner) || IsHTMLOListElement(runner))
+    if (IsHTMLUListElement(runner) || IsA<HTMLOListElement>(runner))
       return To<HTMLElement>(&runner);
     if (runner == root)
       return nullptr;
diff --git a/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc b/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
index 7e9b712..8aa3caee 100644
--- a/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
@@ -55,7 +55,7 @@
     return false;
   // TODO(yosin): We should check OL/UL element has "list-style-type" CSS
   // property to make sure they layout contents as list.
-  return IsHTMLUListElement(*element) || IsHTMLOListElement(*element) ||
+  return IsHTMLUListElement(*element) || IsA<HTMLOListElement>(*element) ||
          element->HasTagName(kBlockquoteTag);
 }
 
@@ -218,7 +218,7 @@
     return;
 
   // Use InsertListCommand to remove the selection from the list
-  if (IsHTMLOListElement(*enclosing_element)) {
+  if (IsA<HTMLOListElement>(*enclosing_element)) {
     ApplyCommandToComposite(MakeGarbageCollected<InsertListCommand>(
                                 GetDocument(), InsertListCommand::kOrderedList),
                             editing_state);
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
index fd599f5..6da40a9 100644
--- a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
@@ -830,7 +830,7 @@
   Node* next = nullptr;
   for (Node* node = fragment.FirstChild(); node; node = next) {
     if (IsA<HTMLBaseElement>(*node) || IsHTMLLinkElement(*node) ||
-        IsHTMLMetaElement(*node) || IsHTMLTitleElement(*node)) {
+        IsA<HTMLMetaElement>(*node) || IsHTMLTitleElement(*node)) {
       next = NodeTraversal::NextSkippingChildren(*node);
       fragment.RemoveNode(node);
     } else {
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc
index 8aef31c..988b71d7 100644
--- a/third_party/blink/renderer/core/editing/editing_utilities.cc
+++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -1109,7 +1109,7 @@
 }
 
 bool IsHTMLListElement(const Node* n) {
-  return (n && (IsHTMLUListElement(*n) || IsHTMLOListElement(*n) ||
+  return (n && (IsHTMLUListElement(*n) || IsA<HTMLOListElement>(*n) ||
                 IsA<HTMLDListElement>(*n)));
 }
 
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer.cc b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
index 8ef026b..a96e206 100644
--- a/third_party/blink/renderer/core/editing/finder/find_buffer.cc
+++ b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
@@ -103,7 +103,7 @@
     return false;
   return (!element->ShouldSerializeEndTag() && !IsHTMLInputElement(*element)) ||
          IsA<HTMLIFrameElement>(*element) || IsHTMLImageElement(*element) ||
-         IsA<HTMLLegendElement>(*element) || IsHTMLMeterElement(*element) ||
+         IsA<HTMLLegendElement>(*element) || IsA<HTMLMeterElement>(*element) ||
          IsHTMLObjectElement(*element) || IsHTMLProgressElement(*element) ||
          (IsHTMLSelectElement(*element) &&
           ToHTMLSelectElement(*element).UsesMenuList()) ||
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
index d25e2ef..3e49eb0d 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
@@ -378,7 +378,7 @@
                        (IsHTMLFormControlElement(html_element) ||
                         IsA<HTMLLegendElement>(html_element) ||
                         IsHTMLImageElement(html_element) ||
-                        IsHTMLMeterElement(html_element) ||
+                        IsA<HTMLMeterElement>(html_element) ||
                         IsHTMLProgressElement(html_element))))) {
             HandleReplacedElement();
           } else {
diff --git a/third_party/blink/renderer/core/exported/web_frame_serializer.cc b/third_party/blink/renderer/core/exported/web_frame_serializer.cc
index ddf240f..6b706fa 100644
--- a/third_party/blink/renderer/core/exported/web_frame_serializer.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_serializer.cc
@@ -181,7 +181,7 @@
   // the saved MHTML page, there is no need to carry the directives. If they
   // are still kept in the MHTML, child frames that are referred to using cid:
   // scheme could be prevented from loading.
-  if (!IsHTMLMetaElement(element))
+  if (!IsA<HTMLMetaElement>(element))
     return false;
   if (!element.FastHasAttribute(html_names::kContentAttr))
     return false;
diff --git a/third_party/blink/renderer/core/exported/web_meta_element.cc b/third_party/blink/renderer/core/exported/web_meta_element.cc
index 213df2a..eb2be51 100644
--- a/third_party/blink/renderer/core/exported/web_meta_element.cc
+++ b/third_party/blink/renderer/core/exported/web_meta_element.cc
@@ -18,7 +18,7 @@
     : WebElement(element) {}
 
 DEFINE_WEB_NODE_TYPE_CASTS(WebMetaElement,
-                           IsHTMLMetaElement(ConstUnwrap<Node>()))
+                           IsA<HTMLMetaElement>(ConstUnwrap<Node>()))
 
 WebMetaElement& WebMetaElement::operator=(HTMLMetaElement* element) {
   private_ = element;
@@ -26,7 +26,7 @@
 }
 
 WebMetaElement::operator HTMLMetaElement*() const {
-  return ToHTMLMetaElement(private_.Get());
+  return blink::To<HTMLMetaElement>(private_.Get());
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_security_policy.cc b/third_party/blink/renderer/core/exported/web_security_policy.cc
index 1e69f21..7af0bca 100644
--- a/third_party/blink/renderer/core/exported/web_security_policy.cc
+++ b/third_party/blink/renderer/core/exported/web_security_policy.cc
@@ -117,9 +117,11 @@
 
 WebString WebSecurityPolicy::GenerateReferrerHeader(
     network::mojom::ReferrerPolicy referrer_policy,
+    const WebSecurityOrigin& origin,
     const WebURL& url,
     const WebString& referrer) {
-  return SecurityPolicy::GenerateReferrer(referrer_policy, url, referrer)
+  return SecurityPolicy::GenerateReferrer(referrer_policy, origin, url,
+                                          referrer)
       .referrer;
 }
 
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc
index ed90060..7803562 100644
--- a/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -473,16 +473,6 @@
               "Creating a MediaStreamAudioSourceNode on an OfflineAudioContext",
               kM71, "5258622686724096")};
 
-    case WebFeature::kGridRowTrackPercentIndefiniteHeight:
-      return {"GridRowTrackPercentIndefiniteHeight", kM70,
-              String::Format("Percentages row tracks and gutters for "
-                             "indefinite height grid containers will be "
-                             "resolved against the intrinsic height instead of "
-                             "being treated as auto and zero respectively. "
-                             "This change will happen in %s. See "
-                             "https://www.chromestatus.com/feature/"
-                             "6708326821789696 for more details.",
-                             MilestoneString(kM70))};
     case WebFeature::kTextToSpeech_SpeakDisallowedByAutoplay:
       return {
           "TextToSpeech_DisallowedByAutoplay", kM71,
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc
index 82753c7..ecc5d4e 100644
--- a/third_party/blink/renderer/core/frame/dom_window.cc
+++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -118,7 +118,7 @@
 void DOMWindow::postMessage(v8::Isolate* isolate,
                             const ScriptValue& message,
                             const String& target_origin,
-                            Vector<ScriptValue>& transfer,
+                            HeapVector<ScriptValue>& transfer,
                             ExceptionState& exception_state) {
   WindowPostMessageOptions* options = WindowPostMessageOptions::Create();
   options->setTargetOrigin(target_origin);
diff --git a/third_party/blink/renderer/core/frame/dom_window.h b/third_party/blink/renderer/core/frame/dom_window.h
index 76237d7..fc9782c 100644
--- a/third_party/blink/renderer/core/frame/dom_window.h
+++ b/third_party/blink/renderer/core/frame/dom_window.h
@@ -98,7 +98,7 @@
   void postMessage(v8::Isolate*,
                    const ScriptValue& message,
                    const String& target_origin,
-                   Vector<ScriptValue>& transfer,
+                   HeapVector<ScriptValue>& transfer,
                    ExceptionState&);
 
   void postMessage(v8::Isolate*,
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc
index a9abd9e..ed83655 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -149,8 +149,8 @@
     return true;
   if (IsHTMLNoScriptElement(element))
     return true;
-  if (IsHTMLMetaElement(element) &&
-      ToHTMLMetaElement(element).ComputeEncoding().IsValid()) {
+  auto* meta = DynamicTo<HTMLMetaElement>(element);
+  if (meta && meta->ComputeEncoding().IsValid()) {
     return true;
   }
   // This is done in serializing document.StyleSheets.
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index ed6afc8..d3f23b0 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1507,9 +1507,12 @@
   // ensure the proper referrer is set now.
   // TODO(domfarolino): Stop setting ResourceRequest's HTTP Referrer and store
   // this is a separate member. See https://crbug.com/850813.
+  const SecurityOrigin* origin =
+      active_document ? active_document->GetSecurityOrigin()
+                      : SecurityOrigin::Create(completed_url).get();
   frame_request.GetResourceRequest().SetHttpReferrer(
       SecurityPolicy::GenerateReferrer(
-          active_document->GetReferrerPolicy(), completed_url,
+          active_document->GetReferrerPolicy(), origin, completed_url,
           window_features.noreferrer ? Referrer::NoReferrer()
                                      : active_document->OutgoingReferrer()));
 
diff --git a/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc b/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
index 143c242d..ed21e87 100644
--- a/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
@@ -142,8 +142,8 @@
     // have overrided the META which have correct charset declaration after
     // serializing open tag of HEAD element.
     DCHECK(element);
-    if (IsHTMLMetaElement(element) &&
-        ToHTMLMetaElement(element)->ComputeEncoding().IsValid()) {
+    auto* meta = DynamicTo<HTMLMetaElement>(element);
+    if (meta && meta->ComputeEncoding().IsValid()) {
       // Found META tag declared charset, we need to skip it when
       // serializing DOM.
       param->skip_meta_element = element;
diff --git a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
index 51e3b0f..e65c733 100644
--- a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
@@ -134,7 +134,7 @@
     EventTarget& event_target,
     V8Function* handler,
     int timeout,
-    const Vector<ScriptValue>& arguments) {
+    const HeapVector<ScriptValue>& arguments) {
   ExecutionContext* execution_context = event_target.GetExecutionContext();
   if (!IsAllowed(script_state, execution_context, false, g_empty_string))
     return 0;
@@ -154,7 +154,7 @@
     EventTarget& event_target,
     const StringOrTrustedScript& string_or_trusted_script,
     int timeout,
-    const Vector<ScriptValue>& arguments,
+    const HeapVector<ScriptValue>& arguments,
     ExceptionState& exception_state) {
   ExecutionContext* execution_context = event_target.GetExecutionContext();
   Document* document = execution_context->IsDocument()
@@ -173,7 +173,7 @@
     EventTarget& event_target,
     const String& handler,
     int timeout,
-    const Vector<ScriptValue>&) {
+    const HeapVector<ScriptValue>&) {
   ExecutionContext* execution_context = event_target.GetExecutionContext();
   if (!IsAllowed(script_state, execution_context, true, handler))
     return 0;
@@ -197,7 +197,7 @@
     EventTarget& event_target,
     V8Function* handler,
     int timeout,
-    const Vector<ScriptValue>& arguments) {
+    const HeapVector<ScriptValue>& arguments) {
   ExecutionContext* execution_context = event_target.GetExecutionContext();
   if (!IsAllowed(script_state, execution_context, false, g_empty_string))
     return 0;
@@ -212,7 +212,7 @@
     EventTarget& event_target,
     const StringOrTrustedScript& string_or_trusted_script,
     int timeout,
-    const Vector<ScriptValue>& arguments,
+    const HeapVector<ScriptValue>& arguments,
     ExceptionState& exception_state) {
   ExecutionContext* execution_context = event_target.GetExecutionContext();
   Document* document = execution_context->IsDocument()
@@ -231,7 +231,7 @@
     EventTarget& event_target,
     const String& handler,
     int timeout,
-    const Vector<ScriptValue>&) {
+    const HeapVector<ScriptValue>&) {
   ExecutionContext* execution_context = event_target.GetExecutionContext();
   if (!IsAllowed(script_state, execution_context, true, handler))
     return 0;
diff --git a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
index e3e7a41..b378abf 100644
--- a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
+++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
@@ -67,34 +67,34 @@
                         EventTarget&,
                         V8Function* handler,
                         int timeout,
-                        const Vector<ScriptValue>& arguments);
+                        const HeapVector<ScriptValue>& arguments);
   static int setTimeout(ScriptState*,
                         EventTarget&,
                         const StringOrTrustedScript&,
                         int timeout,
-                        const Vector<ScriptValue>&,
+                        const HeapVector<ScriptValue>&,
                         ExceptionState&);
   static int setTimeoutFromString(ScriptState*,
                                   EventTarget&,
                                   const String& handler,
                                   int timeout,
-                                  const Vector<ScriptValue>&);
+                                  const HeapVector<ScriptValue>&);
   static int setInterval(ScriptState*,
                          EventTarget&,
                          V8Function* handler,
                          int timeout,
-                         const Vector<ScriptValue>&);
+                         const HeapVector<ScriptValue>&);
   static int setInterval(ScriptState*,
                          EventTarget&,
                          const StringOrTrustedScript&,
                          int timeout,
-                         const Vector<ScriptValue>&,
+                         const HeapVector<ScriptValue>&,
                          ExceptionState&);
   static int setIntervalFromString(ScriptState*,
                                    EventTarget&,
                                    const String& handler,
                                    int timeout,
-                                   const Vector<ScriptValue>&);
+                                   const HeapVector<ScriptValue>&);
   static void clearTimeout(EventTarget&, int timeout_id);
   static void clearInterval(EventTarget&, int timeout_id);
 
diff --git a/third_party/blink/renderer/core/html/html_li_element.cc b/third_party/blink/renderer/core/html/html_li_element.cc
index e084d98e..eaed193 100644
--- a/third_party/blink/renderer/core/html/html_li_element.cc
+++ b/third_party/blink/renderer/core/html/html_li_element.cc
@@ -102,7 +102,7 @@
       current = LayoutTreeBuilderTraversal::ParentElement(*current);
       if (!current)
         break;
-      if (IsHTMLUListElement(*current) || IsHTMLOListElement(*current))
+      if (IsHTMLUListElement(*current) || IsA<HTMLOListElement>(*current))
         list_node = current;
     }
 
diff --git a/third_party/blink/renderer/core/html/html_meta_element_test.cc b/third_party/blink/renderer/core/html/html_meta_element_test.cc
index c173147..11fcd11 100644
--- a/third_party/blink/renderer/core/html/html_meta_element_test.cc
+++ b/third_party/blink/renderer/core/html/html_meta_element_test.cc
@@ -55,8 +55,7 @@
   }
 
   void SetColorScheme(const AtomicString& content) {
-    HTMLMetaElement* meta =
-        ToHTMLMetaElement(GetDocument().head()->firstChild());
+    auto* meta = To<HTMLMetaElement>(GetDocument().head()->firstChild());
     ASSERT_TRUE(meta);
     meta->setAttribute(html_names::kContentAttr, content);
   }
diff --git a/third_party/blink/renderer/core/html/list_item_ordinal.cc b/third_party/blink/renderer/core/html/list_item_ordinal.cc
index 67e4d57..4cff543 100644
--- a/third_party/blink/renderer/core/html/list_item_ordinal.cc
+++ b/third_party/blink/renderer/core/html/list_item_ordinal.cc
@@ -39,7 +39,7 @@
     : type_(kNeedsUpdate), not_in_list_(false), not_in_list_changed_(false) {}
 
 bool ListItemOrdinal::IsList(const Node& node) {
-  return IsHTMLUListElement(node) || IsHTMLOListElement(node);
+  return IsHTMLUListElement(node) || IsA<HTMLOListElement>(node);
 }
 
 bool ListItemOrdinal::IsListItem(const LayoutObject* layout_object) {
@@ -162,7 +162,7 @@
     return value_;
 
   Node* list = EnclosingList(&item_node);
-  HTMLOListElement* o_list_element = ToHTMLOListElementOrNull(list);
+  auto* o_list_element = DynamicTo<HTMLOListElement>(list);
   int value_step = 1;
   if (o_list_element && o_list_element->IsReversed())
     value_step = -1;
@@ -296,7 +296,7 @@
   CHECK(list_node);
 
   bool is_list_reversed = false;
-  if (auto* o_list_element = ToHTMLOListElementOrNull(list_node)) {
+  if (auto* o_list_element = DynamicTo<HTMLOListElement>(list_node)) {
     o_list_element->ItemCountChanged();
     is_list_reversed = o_list_element->IsReversed();
   }
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
index 062cf95..e1ecfe38 100644
--- a/third_party/blink/renderer/core/html/portal/html_portal_element.cc
+++ b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -131,7 +131,8 @@
   if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault)
     referrer_policy_to_use = GetDocument().GetReferrerPolicy();
   Referrer referrer = SecurityPolicy::GenerateReferrer(
-      referrer_policy_to_use, url, GetDocument().OutgoingReferrer());
+      referrer_policy_to_use, GetDocument().GetSecurityOrigin(), url,
+      GetDocument().OutgoingReferrer());
   auto mojo_referrer = mojom::blink::Referrer::New(
       KURL(NullURL(), referrer.referrer), referrer.referrer_policy);
 
@@ -258,7 +259,7 @@
 void HTMLPortalElement::postMessage(ScriptState* script_state,
                                     const ScriptValue& message,
                                     const String& target_origin,
-                                    const Vector<ScriptValue>& transfer,
+                                    const HeapVector<ScriptValue>& transfer,
                                     ExceptionState& exception_state) {
   WindowPostMessageOptions* options = WindowPostMessageOptions::Create();
   options->setTargetOrigin(target_origin);
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.h b/third_party/blink/renderer/core/html/portal/html_portal_element.h
index 783533b..60f122d 100644
--- a/third_party/blink/renderer/core/html/portal/html_portal_element.h
+++ b/third_party/blink/renderer/core/html/portal/html_portal_element.h
@@ -48,7 +48,7 @@
   void postMessage(ScriptState* script_state,
                    const ScriptValue& message,
                    const String& target_origin,
-                   const Vector<ScriptValue>& transfer,
+                   const HeapVector<ScriptValue>& transfer,
                    ExceptionState& exception_state);
   void postMessage(ScriptState* script_state,
                    const ScriptValue& message,
diff --git a/third_party/blink/renderer/core/html/portal/portal_host.cc b/third_party/blink/renderer/core/html/portal/portal_host.cc
index 706104f..42b6924 100644
--- a/third_party/blink/renderer/core/html/portal/portal_host.cc
+++ b/third_party/blink/renderer/core/html/portal/portal_host.cc
@@ -65,7 +65,7 @@
 void PortalHost::postMessage(ScriptState* script_state,
                              const ScriptValue& message,
                              const String& target_origin,
-                             Vector<ScriptValue>& transfer,
+                             HeapVector<ScriptValue>& transfer,
                              ExceptionState& exception_state) {
   WindowPostMessageOptions* options = WindowPostMessageOptions::Create();
   options->setTargetOrigin(target_origin);
diff --git a/third_party/blink/renderer/core/html/portal/portal_host.h b/third_party/blink/renderer/core/html/portal/portal_host.h
index 24fa31c5..b23977c 100644
--- a/third_party/blink/renderer/core/html/portal/portal_host.h
+++ b/third_party/blink/renderer/core/html/portal/portal_host.h
@@ -48,7 +48,7 @@
   void postMessage(ScriptState* script_state,
                    const ScriptValue& message,
                    const String& target_origin,
-                   Vector<ScriptValue>& transfer,
+                   HeapVector<ScriptValue>& transfer,
                    ExceptionState& exception_state);
   void postMessage(ScriptState* script_state,
                    const ScriptValue& message,
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
index c877e5c..8d6b0ecc 100644
--- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
@@ -135,7 +135,6 @@
     return false;
   }
   LayoutUnit FreeSpaceForStretchAutoTracksStep() const override;
-  LayoutUnit MinContentForChild(LayoutBox&) const override;
   bool IsComputingSizeContainment() const override { return false; }
 };
 
@@ -150,15 +149,10 @@
       GridLayoutUtils::FlowAwareDirectionForChild(grid, child, kForColumns);
   if (direction == child_inline_direction) {
     return child.HasRelativeLogicalWidth() ||
-           child.StyleRef().LogicalWidth().IsIntrinsicOrAuto() ||
-           child.StyleRef().MarginStart().IsPercentOrCalc() ||
-           child.StyleRef().MarginEnd().IsPercentOrCalc();
+           child.StyleRef().LogicalWidth().IsIntrinsicOrAuto();
   }
   return child.HasRelativeLogicalHeight() ||
-         child.StyleRef().LogicalHeight().IsIntrinsicOrAuto() ||
-         child.StyleRef().MarginBefore().IsPercentOrCalc() ||
-         child.StyleRef().MarginAfter().IsPercentOrCalc();
-  ;
+         child.StyleRef().LogicalHeight().IsIntrinsicOrAuto();
 }
 
 void GridTrackSizingAlgorithmStrategy::
@@ -583,21 +577,6 @@
   return algorithm_.FreeSpace(Direction()).value();
 }
 
-DISABLE_CFI_PERF
-LayoutUnit DefiniteSizeStrategy::MinContentForChild(LayoutBox& child) const {
-  GridTrackSizingDirection child_inline_direction =
-      GridLayoutUtils::FlowAwareDirectionForChild(*GetLayoutGrid(), child,
-                                                  kForColumns);
-  if (Direction() == child_inline_direction &&
-      ShouldClearOverrideContainingBlockContentSizeForChild(
-          *GetLayoutGrid(), child, child_inline_direction)) {
-    SetOverrideContainingBlockContentSizeForChild(child, child_inline_direction,
-                                                  LayoutUnit());
-  }
-
-  return GridTrackSizingAlgorithmStrategy::MinContentForChild(child);
-}
-
 void IndefiniteSizeStrategy::LayoutGridItemForMinSizeComputation(
     LayoutBox& child,
     bool override_size_has_changed) const {
@@ -894,9 +873,8 @@
   // values are treated as <auto>.
   if (IsRelativeSizedTrackAsAuto(track_size, direction)) {
     if (direction == kForRows) {
-      Deprecation::CountDeprecation(
-          layout_grid_->GetDocument(),
-          WebFeature::kGridRowTrackPercentIndefiniteHeight);
+      UseCounter::Count(layout_grid_->GetDocument(),
+                        WebFeature::kGridRowTrackPercentIndefiniteHeight);
     }
     if (min_track_breadth.HasPercentage())
       min_track_breadth = Length::Auto();
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 29c0f7e5..d76005f 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -2870,7 +2870,7 @@
   DCHECK(layout_object);
   Node* parent_node = layout_object->GeneratingNode();
   DCHECK(parent_node);
-  DCHECK(IsHTMLOListElement(parent_node) || IsHTMLUListElement(parent_node));
+  DCHECK(IsA<HTMLOListElement>(parent_node) || IsHTMLUListElement(parent_node));
   DCHECK_NE(layout_object->StyleRef().TextAutosizingMultiplier(), 1);
 #endif
   float max_width = 0;
@@ -3011,7 +3011,7 @@
   if (style_to_use.TextAutosizingMultiplier() != 1 &&
       style_to_use.MarginStart().IsFixed()) {
     Node* parent_node = GeneratingNode();
-    if (parent_node && (IsHTMLOListElement(*parent_node) ||
+    if (parent_node && (IsA<HTMLOListElement>(*parent_node) ||
                         IsHTMLUListElement(*parent_node))) {
       // Make sure the markers in a list are properly positioned (i.e. not
       // chopped off) when autosized.
diff --git a/third_party/blink/renderer/core/layout/layout_counter.cc b/third_party/blink/renderer/core/layout/layout_counter.cc
index b7f4bd4..23c9d72 100644
--- a/third_party/blink/renderer/core/layout/layout_counter.cc
+++ b/third_party/blink/renderer/core/layout/layout_counter.cc
@@ -185,7 +185,7 @@
         is_reset = false;
         return true;
       }
-      if (auto* olist = ToHTMLOListElementOrNull(*e)) {
+      if (auto* olist = DynamicTo<HTMLOListElement>(*e)) {
         value = olist->StartConsideringItemCount();
         is_reset = true;
         return true;
diff --git a/third_party/blink/renderer/core/layout/layout_list_item.cc b/third_party/blink/renderer/core/layout/layout_list_item.cc
index a584f566..562427b 100644
--- a/third_party/blink/renderer/core/layout/layout_list_item.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_item.cc
@@ -147,7 +147,7 @@
 
     if (curr->IsListItem() && in_quirks_mode && curr_child->GetNode() &&
         (IsHTMLUListElement(*curr_child->GetNode()) ||
-         IsHTMLOListElement(*curr_child->GetNode())))
+         IsA<HTMLOListElement>(*curr_child->GetNode())))
       break;
 
     LayoutObject* line_box = GetParentOfFirstLineBox(child_block_flow, marker);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc
index da4b412..e03cf0a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc
@@ -125,6 +125,19 @@
             GetItemsAsString(*text.GetLayoutObject()));
 }
 
+// http://crbug.com/1000685
+TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteRTL2) {
+  if (!RuntimeEnabledFeatures::LayoutNGEnabled())
+    return;
+
+  SetBodyInnerHTML(u"<p id=target dir=rtl>0(xy)5</p>");
+  Text& text = To<Text>(*GetElementById("target")->firstChild());
+  text.deleteData(0, 1, ASSERT_NO_EXCEPTION);  // remove "0"
+
+  EXPECT_EQ("*{'(xy)5', ShapeResult=0+5}\n",
+            GetItemsAsString(*text.GetLayoutObject()));
+}
+
 TEST_F(LayoutNGTextTest, SetTextWithOffsetInsert) {
   if (!RuntimeEnabledFeatures::LayoutNGEnabled())
     return;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
index cf430a6..79775026 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
@@ -147,8 +147,8 @@
   if (!fragment_)
     return 0;
   if (NeedsTrailingSpace())
-    return PhysicalTextFragment().Length() + 1;
-  return PhysicalTextFragment().Length();
+    return PhysicalTextFragment().TextLength() + 1;
+  return PhysicalTextFragment().TextLength();
 }
 
 AbstractInlineTextBox::Direction NGAbstractInlineTextBox::GetDirection() const {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
index 98e7f5e..5397a62b 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -200,6 +200,11 @@
     return Style().GetWritingMode();
   }
 
+  // TODO(yosin): We'll implement following functions.
+  bool IsLineBreak() const { return false; }
+  bool IsEllipsis() const { return false; }
+  bool IsSymbolMarker() const { return false; }
+
   const ShapeResultView* TextShapeResult() const;
 
   unsigned StartOffset() const;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
index 74053c0..773066d 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
@@ -55,7 +55,8 @@
   NOTREACHED();
 }
 
-NGInlineCursor::NGInlineCursor(const NGFragmentItems& items) {
+NGInlineCursor::NGInlineCursor(const NGFragmentItems& items)
+    : fragment_items_(&items) {
   SetRoot(items);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
index 6468d9d5..d0be72ea3 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
@@ -51,6 +51,10 @@
   }
   const NGPhysicalBoxFragment* CurrentBoxFragment() const;
   const LayoutObject* CurrentLayoutObject() const;
+  const NGFragmentItems& Items() const {
+    DCHECK(fragment_items_);
+    return *fragment_items_;
+  }
 
   // The offset relative to the root of the inline formatting context.
   const PhysicalOffset CurrentOffset() const;
@@ -88,6 +92,7 @@
   ItemsSpan items_;
   ItemsSpan::iterator item_iter_;
   const NGFragmentItem* current_item_ = nullptr;
+  const NGFragmentItems* fragment_items_ = nullptr;
 
   const NGPaintFragment* root_paint_fragment_ = nullptr;
   const NGPaintFragment* current_paint_fragment_ = nullptr;
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 f0060ca..c6a12ea 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
@@ -614,7 +614,6 @@
     // Copy items after replaced range
     ++it;
     while (it != data_->items.end()) {
-      DCHECK_NE(it->layout_object_, layout_text_);
       DCHECK_LE(end_offset, it->start_offset_);
       items.push_back(*it);
       ShiftItem(&items.back(), diff);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
index ddadc09..0014fe3 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
@@ -249,8 +249,8 @@
       IsLtr(line_direction_) ? space_for_child
                              : shape_result->Width() - space_for_child,
       line_direction_);
-  DCHECK_LE(new_length, fragment.Length());
-  if (!new_length || new_length == fragment.Length()) {
+  DCHECK_LE(new_length, fragment.TextLength());
+  if (!new_length || new_length == fragment.TextLength()) {
     if (!is_first_child)
       return false;
     new_length = !new_length ? 1 : new_length - 1;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
index 6d97f33..66ec0ce 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
@@ -244,7 +244,7 @@
   LayoutUnit inline_offset = IsLtr(ResolvedDirection())
                                  ? point_in_line_direction
                                  : size.inline_size - point_in_line_direction;
-  DCHECK_EQ(1u, Length());
+  DCHECK_EQ(1u, TextLength());
   return inline_offset <= size.inline_size / 2 ? StartOffset() : EndOffset();
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h
index 3b1d69d..921af7d 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h
@@ -61,8 +61,12 @@
     return StyleVariant() == NGStyleVariant::kEllipsis;
   }
 
-  unsigned Length() const { return end_offset_ - start_offset_; }
-  StringView Text() const { return StringView(text_, start_offset_, Length()); }
+  bool IsSymbolMarker() const { return TextType() == kSymbolMarker; }
+
+  unsigned TextLength() const { return end_offset_ - start_offset_; }
+  StringView Text() const {
+    return StringView(text_, start_offset_, TextLength());
+  }
   const String& TextContent() const { return text_; }
 
   // ShapeResult may be nullptr if |IsFlowControl()|.
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc
index 06b7732..bcf4880 100644
--- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc
@@ -47,7 +47,7 @@
   LayoutObject* next_sibling = NextSibling();
   if (next_sibling && next_sibling->GetNode() &&
       (IsHTMLUListElement(*next_sibling->GetNode()) ||
-       IsHTMLOListElement(*next_sibling->GetNode())))
+       IsA<HTMLOListElement>(*next_sibling->GetNode())))
     return true;
 
   return false;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc b/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc
index 1be5ea7..13a027e0 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc
@@ -16,7 +16,7 @@
     float text_decoration_thickness,
     FontVerticalPositionType position_type) const {
   LayoutUnit offset = LayoutUnit::Max();
-  const ComputedStyle& style = text_item_.Style();
+  const ComputedStyle& style = text_style_;
   FontBaseline baseline_type = style.GetFontBaseline();
 
   if (decorating_box_) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.h b/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.h
index 125d2b3..057705e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.h
@@ -11,7 +11,6 @@
 namespace blink {
 
 class ComputedStyle;
-class NGFragmentItem;
 class NGPhysicalBoxFragment;
 
 // Class for computing the decoration offset for text fragments in LayoutNG.
@@ -20,10 +19,10 @@
 
  public:
   NGTextDecorationOffset(const ComputedStyle& style,
-                         const NGFragmentItem& text_item,
+                         const ComputedStyle& text_style,
                          const NGPhysicalBoxFragment* decorating_box)
       : TextDecorationOffsetBase(style),
-        text_item_(text_item),
+        text_style_(text_style),
         decorating_box_(decorating_box) {}
   ~NGTextDecorationOffset() = default;
 
@@ -31,7 +30,7 @@
                                      FontVerticalPositionType) const override;
 
  private:
-  const NGFragmentItem& text_item_;
+  const ComputedStyle& text_style_;
   const NGPhysicalBoxFragment* decorating_box_;
 };
 
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index 0fbb6e1..cc21874e 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -496,8 +496,12 @@
     history_item_ = MakeGarbageCollected<HistoryItem>();
 
   history_item_->SetURL(UrlForHistory());
+  scoped_refptr<const SecurityOrigin> origin =
+      requestor_origin_ ? requestor_origin_
+                        : SecurityOrigin::CreateUniqueOpaque();
   history_item_->SetReferrer(SecurityPolicy::GenerateReferrer(
-      referrer_.referrer_policy, history_item_->Url(), referrer_.referrer));
+      referrer_.referrer_policy, origin, history_item_->Url(),
+      referrer_.referrer));
   if (DeprecatedEqualIgnoringCase(http_method_, "POST")) {
     // FIXME: Eventually we have to make this smart enough to handle the case
     // where we have a stream for the body to handle the "data interspersed with
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.cc b/third_party/blink/renderer/core/loader/frame_load_request.cc
index 270ec3c..7c3b3e9 100644
--- a/third_party/blink/renderer/core/loader/frame_load_request.cc
+++ b/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -34,7 +34,8 @@
     referrer_policy_to_use = origin_document->GetReferrerPolicy();
 
   Referrer referrer = SecurityPolicy::GenerateReferrer(
-      referrer_policy_to_use, request.Url(), referrer_to_use);
+      referrer_policy_to_use, request.RequestorOrigin(), request.Url(),
+      referrer_to_use);
 
   // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
   // header and instead use a separate member. See https://crbug.com/850813.
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 9b44389..78b897b 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -158,6 +158,7 @@
   if (client_redirect_policy == ClientRedirectPolicy::kClientRedirect) {
     request.SetHttpReferrer(SecurityPolicy::GenerateReferrer(
         frame_->GetDocument()->GetReferrerPolicy(),
+        frame_->GetDocument()->GetSecurityOrigin(),
         frame_->GetDocument()->Url(),
         frame_->GetDocument()->OutgoingReferrer()));
   }
diff --git a/third_party/blink/renderer/core/loader/history_item.cc b/third_party/blink/renderer/core/loader/history_item.cc
index a9131543..3473069 100644
--- a/third_party/blink/renderer/core/loader/history_item.cc
+++ b/third_party/blink/renderer/core/loader/history_item.cc
@@ -75,8 +75,11 @@
 
 void HistoryItem::SetReferrer(const Referrer& referrer) {
   // This should be a CHECK.
-  referrer_ = SecurityPolicy::GenerateReferrer(referrer.referrer_policy, Url(),
-                                               referrer.referrer);
+  // TODO(domfarolino): Should this function take an |origin| parameter?
+  referrer_ = SecurityPolicy::GenerateReferrer(
+      referrer.referrer_policy,
+      SecurityOrigin::CreateFromString(referrer.referrer), Url(),
+      referrer.referrer);
 }
 
 void HistoryItem::SetVisualViewportScrollOffset(const ScrollOffset& offset) {
diff --git a/third_party/blink/renderer/core/loader/private/prerender_handle.cc b/third_party/blink/renderer/core/loader/private/prerender_handle.cc
index 01aaa28..88e0b11 100644
--- a/third_party/blink/renderer/core/loader/private/prerender_handle.cc
+++ b/third_party/blink/renderer/core/loader/private/prerender_handle.cc
@@ -53,7 +53,8 @@
 
   auto* prerender = MakeGarbageCollected<Prerender>(
       client, url, prerender_rel_types,
-      SecurityPolicy::GenerateReferrer(document.GetReferrerPolicy(), url,
+      SecurityPolicy::GenerateReferrer(document.GetReferrerPolicy(),
+                                       document.GetSecurityOrigin(), url,
                                        document.OutgoingReferrer()),
       document.GetSecurityOrigin());
 
diff --git a/third_party/blink/renderer/core/messaging/message_port.cc b/third_party/blink/renderer/core/messaging/message_port.cc
index 62ca430..253da24 100644
--- a/third_party/blink/renderer/core/messaging/message_port.cc
+++ b/third_party/blink/renderer/core/messaging/message_port.cc
@@ -65,7 +65,7 @@
 
 void MessagePort::postMessage(ScriptState* script_state,
                               const ScriptValue& message,
-                              Vector<ScriptValue>& transfer,
+                              HeapVector<ScriptValue>& transfer,
                               ExceptionState& exception_state) {
   PostMessageOptions* options = PostMessageOptions::Create();
   if (!transfer.IsEmpty())
diff --git a/third_party/blink/renderer/core/messaging/message_port.h b/third_party/blink/renderer/core/messaging/message_port.h
index 1f9f0b4..b6ae50f 100644
--- a/third_party/blink/renderer/core/messaging/message_port.h
+++ b/third_party/blink/renderer/core/messaging/message_port.h
@@ -62,7 +62,7 @@
 
   void postMessage(ScriptState*,
                    const ScriptValue& message,
-                   Vector<ScriptValue>& transfer,
+                   HeapVector<ScriptValue>& transfer,
                    ExceptionState&);
   void postMessage(ScriptState*,
                    const ScriptValue& message,
diff --git a/third_party/blink/renderer/core/paint/inline_painter.cc b/third_party/blink/renderer/core/paint/inline_painter.cc
index 938fda8f..f9efbc67 100644
--- a/third_party/blink/renderer/core/paint/inline_painter.cc
+++ b/third_party/blink/renderer/core/paint/inline_painter.cc
@@ -50,7 +50,9 @@
                           fragment->Offset();
 
       if (fragment->PhysicalFragment().IsText()) {
-        NGTextFragmentPainter(*fragment).Paint(paint_info, child_offset);
+        NGTextPainterCursor cursor(*fragment);
+        NGTextFragmentPainter<NGTextPainterCursor>(cursor).Paint(paint_info,
+                                                                 child_offset);
       } else {
         NGInlineBoxFragmentPainter(*fragment).Paint(paint_info, child_offset);
       }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index a33bba13..26e03a7 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -885,7 +885,7 @@
     DCHECK(item);
     switch (item->Type()) {
       case NGFragmentItem::kText:
-        PaintTextItem(*item, paint_info, paint_offset);
+        PaintTextItem(cursor, paint_info, paint_offset);
         break;
       case NGFragmentItem::kGeneratedText:
         // TODO(kojii): Implement.
@@ -1094,14 +1094,15 @@
       paint_info.phase != PaintPhase::kMask)
     return;
 
-  NGTextFragmentPainter text_painter(paint_fragment);
+  NGTextPainterCursor cursor(paint_fragment);
+  NGTextFragmentPainter<NGTextPainterCursor> text_painter(cursor);
   text_painter.Paint(paint_info, paint_offset);
 }
 
-void NGBoxFragmentPainter::PaintTextItem(const NGFragmentItem& item,
+void NGBoxFragmentPainter::PaintTextItem(const NGInlineCursor& cursor,
                                          const PaintInfo& paint_info,
                                          const PhysicalOffset& paint_offset) {
-  DCHECK_EQ(item.Type(), NGFragmentItem::kText);
+  DCHECK_EQ(cursor.CurrentItem()->Type(), NGFragmentItem::kText);
   DCHECK(items_);
 
   // Only paint during the foreground/selection phases.
@@ -1111,7 +1112,7 @@
       paint_info.phase != PaintPhase::kMask)
     return;
 
-  NGTextFragmentPainter text_painter(item, *items_);
+  NGTextFragmentPainter<NGInlineCursor> text_painter(cursor);
   text_painter.Paint(paint_info, paint_offset);
 }
 
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
index 6675bb4..7bb7120 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
@@ -22,6 +22,7 @@
 class HitTestRequest;
 class HitTestResult;
 class NGFragmentItems;
+class NGInlineCursor;
 class NGPhysicalFragment;
 class ScopedPaintState;
 struct PaintInfo;
@@ -101,7 +102,7 @@
   void PaintTextChild(const NGPaintFragment&,
                       const PaintInfo&,
                       const PhysicalOffset& paint_offset);
-  void PaintTextItem(const NGFragmentItem& item,
+  void PaintTextItem(const NGInlineCursor& cursor,
                      const PaintInfo&,
                      const PhysicalOffset& paint_offset);
   MoveTo PaintBoxItem(const NGFragmentItem& item,
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
index f20c7cf..047e1ec 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -209,6 +209,7 @@
     return offset_;
   }
   PhysicalSize Size() const { return PhysicalFragment().Size(); }
+  PhysicalRect Rect() const { return {Offset(), Size()}; }
 
   // Converts the given point, relative to the fragment itself, into a position
   // in DOM tree.
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
index 749f195..7e33157 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/layout/geometry/logical_rect.h"
 #include "third_party/blink/renderer/core/layout/layout_list_marker.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment.h"
@@ -52,6 +53,83 @@
   return color;
 }
 
+// TODO(yosin): Remove |AsDisplayItemClient| once the transition to
+// |NGFragmentItem| is done. http://crbug.com/982194
+inline const NGFragmentItem& AsDisplayItemClient(const NGInlineCursor& cursor) {
+  return *cursor.CurrentItem();
+}
+
+inline const NGPaintFragment& AsDisplayItemClient(
+    const NGTextPainterCursor& cursor) {
+  return cursor.PaintFragment();
+}
+
+// TODO(yosin): Remove |GetTextFragmentPaintInfo| once the transition to
+// |NGFragmentItem| is done. http://crbug.com/982194
+inline NGTextFragmentPaintInfo GetTextFragmentPaintInfo(
+    const NGInlineCursor& cursor) {
+  return cursor.CurrentItem()->TextPaintInfo(cursor.Items());
+}
+
+inline NGTextFragmentPaintInfo GetTextFragmentPaintInfo(
+    const NGTextPainterCursor& cursor) {
+  return cursor.CurrentItem()->PaintInfo();
+}
+
+// TODO(yosin): Remove |GetLineLeftAndRightForOffsets| once the transition to
+// |NGFragmentItem| is done. http://crbug.com/982194
+inline std::pair<LayoutUnit, LayoutUnit> GetLineLeftAndRightForOffsets(
+    const NGFragmentItem& text_item,
+    StringView text,
+    unsigned start_offset,
+    unsigned end_offset) {
+  return text_item.LineLeftAndRightForOffsets(text, start_offset, end_offset);
+}
+
+inline std::pair<LayoutUnit, LayoutUnit> GetLineLeftAndRightForOffsets(
+    const NGPhysicalTextFragment& text_fragment,
+    StringView text,
+    unsigned start_offset,
+    unsigned end_offset) {
+  return text_fragment.LineLeftAndRightForOffsets(start_offset, end_offset);
+}
+
+// TODO(yosin): Remove |ComputeLayoutSelectionStatus| once the transition to
+// |NGFragmentItem| is done. http://crbug.com/982194
+inline LayoutSelectionStatus ComputeLayoutSelectionStatus(
+    const NGInlineCursor& cursor) {
+  // TODO(yosin): We should implement |NGInlineCursor| version of
+  // ComputeLayoutSelectionStatus
+  return LayoutSelectionStatus(0, 0, SelectSoftLineBreak::kNotSelected);
+}
+
+inline LayoutSelectionStatus ComputeLayoutSelectionStatus(
+    const NGTextPainterCursor& cursor) {
+  return cursor.CurrentItem()
+      ->GetLayoutObject()
+      ->GetDocument()
+      .GetFrame()
+      ->Selection()
+      .ComputeLayoutSelectionStatus(cursor.PaintFragment());
+}
+
+// TODO(yosin): Remove |ComputeLocalRect| once the transition to
+// |NGFragmentItem| is done. http://crbug.com/982194
+inline PhysicalRect ComputeLocalRect(const NGFragmentItem& text_item,
+                                     StringView text,
+                                     unsigned start_offset,
+                                     unsigned end_offset) {
+  return text_item.LocalRect(text, start_offset, end_offset);
+}
+
+inline PhysicalRect ComputeLocalRect(
+    const NGPhysicalTextFragment& text_fragment,
+    StringView text,
+    unsigned start_offset,
+    unsigned end_offset) {
+  return text_fragment.LocalRect(start_offset, end_offset);
+}
+
 DocumentMarkerVector ComputeMarkersToPaint(Node* node, bool is_ellipsis) {
   // TODO(yoichio): Handle first-letter
   auto* text_node = DynamicTo<Text>(node);
@@ -89,7 +167,8 @@
 // If "bar" is a TextFragment. That start(), end() {4, 7} correspond this
 // offset. If a marker has StartOffset / EndOffset as {2, 6},
 // ClampOffset returns{ 4,6 }, which represents "ba" on "foo_bar".
-unsigned ClampOffset(unsigned offset, const NGFragmentItem& text_fragment) {
+template <typename TextItem>
+unsigned ClampOffset(unsigned offset, const TextItem& text_fragment) {
   return std::min(std::max(offset, text_fragment.StartOffset()),
                   text_fragment.EndOffset());
 }
@@ -108,13 +187,14 @@
     context.FillRect(pixel_snapped_rect, color);
 }
 
-PhysicalRect MarkerRectForForeground(const NGFragmentItem& text_fragment,
+template <typename TextItem>
+PhysicalRect MarkerRectForForeground(const TextItem& text_fragment,
                                      StringView text,
                                      unsigned start_offset,
                                      unsigned end_offset) {
   LayoutUnit start_position, end_position;
-  std::tie(start_position, end_position) =
-      text_fragment.LineLeftAndRightForOffsets(text, start_offset, end_offset);
+  std::tie(start_position, end_position) = GetLineLeftAndRightForOffsets(
+      text_fragment, text, start_offset, end_offset);
 
   const LayoutUnit height = text_fragment.Size()
                                 .ConvertToLogical(static_cast<WritingMode>(
@@ -124,8 +204,9 @@
 }
 
 // Copied from InlineTextBoxPainter
+template <typename TextItem>
 void PaintDocumentMarkers(GraphicsContext& context,
-                          const NGFragmentItem& text_fragment,
+                          const TextItem& text_fragment,
                           StringView text,
                           const DocumentMarkerVector& markers_to_paint,
                           const PhysicalOffset& box_origin,
@@ -177,8 +258,8 @@
                   text_fragment.GetNode()->GetDocument().InForcedColorsMode(),
                   style.UsedColorScheme());
           PaintRect(context, PhysicalOffset(box_origin),
-                    text_fragment.LocalRect(text, paint_start_offset,
-                                            paint_end_offset),
+                    ComputeLocalRect(text_fragment, text, paint_start_offset,
+                                     paint_end_offset),
                     color);
           break;
         }
@@ -200,8 +281,8 @@
         const auto& styleable_marker = To<StyleableMarker>(*marker);
         if (marker_paint_phase == DocumentMarkerPaintPhase::kBackground) {
           PaintRect(context, PhysicalOffset(box_origin),
-                    text_fragment.LocalRect(text, paint_start_offset,
-                                            paint_end_offset),
+                    ComputeLocalRect(text_fragment, text, paint_start_offset,
+                                     paint_end_offset),
                     styleable_marker.BackgroundColor());
           break;
         }
@@ -222,23 +303,26 @@
 
 }  // namespace
 
-NGTextFragmentPainter::NGTextFragmentPainter(
-    const NGPaintFragment& paint_fragment)
-    : paint_fragment_(&paint_fragment),
-      text_fragment_(
-          &To<NGPhysicalTextFragment>(paint_fragment.PhysicalFragment())) {}
-
-NGTextFragmentPainter::NGTextFragmentPainter(const NGFragmentItem& item,
-                                             const NGFragmentItems& items)
-    : item_(&item), items_(&items) {
-  DCHECK_EQ(item.Type(), NGFragmentItem::kText);
-}
+template <typename Cursor>
+NGTextFragmentPainter<Cursor>::NGTextFragmentPainter(const Cursor& cursor)
+    : cursor_(cursor) {}
 
 // Logic is copied from InlineTextBoxPainter::PaintSelection.
 // |selection_start| and |selection_end| should be between
 // [text_fragment.StartOffset(), text_fragment.EndOffset()].
+// TODO(yosin): We should implement |NGInlineCursor| version of
+// |PaintSelection()|
 static void PaintSelection(GraphicsContext& context,
-                           const NGPaintFragment& paint_fragment,
+                           const NGInlineCursor& cursor,
+                           Node* node,
+                           const Document& document,
+                           const ComputedStyle& style,
+                           Color text_color,
+                           const PhysicalRect& box_rect,
+                           const LayoutSelectionStatus& selection_status) {}
+
+static void PaintSelection(GraphicsContext& context,
+                           const NGTextPainterCursor& cursor,
                            Node* node,
                            const Document& document,
                            const ComputedStyle& style,
@@ -248,15 +332,17 @@
   const Color color =
       SelectionBackgroundColor(document, style, node, text_color);
   const PhysicalRect selection_rect =
-      paint_fragment.ComputeLocalSelectionRectForText(selection_status);
+      cursor.PaintFragment().ComputeLocalSelectionRectForText(selection_status);
   PaintRect(context, box_rect.offset, selection_rect, color);
 }
 
-void NGTextFragmentPainter::PaintSymbol(const LayoutObject* layout_object,
-                                        const ComputedStyle& style,
-                                        const PhysicalSize box_size,
-                                        const PaintInfo& paint_info,
-                                        const PhysicalOffset& paint_offset) {
+template <typename Cursor>
+void NGTextFragmentPainter<Cursor>::PaintSymbol(
+    const LayoutObject* layout_object,
+    const ComputedStyle& style,
+    const PhysicalSize box_size,
+    const PaintInfo& paint_info,
+    const PhysicalOffset& paint_offset) {
   PhysicalRect marker_rect(
       LayoutListMarker::RelativeSymbolMarkerRect(style, box_size.width));
   marker_rect.Move(paint_offset);
@@ -267,64 +353,27 @@
 
 // This is copied from InlineTextBoxPainter::PaintSelection() but lacks of
 // ltr, expanding new line wrap or so which uses InlineTextBox functions.
-void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
-                                  const PhysicalOffset& paint_offset) {
-  if (UNLIKELY(item_)) {
-    PaintItem(paint_info, paint_offset);
-    return;
-  }
-  DCHECK(text_fragment_ && paint_fragment_);
-
+template <typename Cursor>
+void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
+                                          const PhysicalOffset& paint_offset) {
+  const auto& text_item = *cursor_.CurrentItem();
   // We can skip painting if the fragment (including selection) is invisible.
-  if (!text_fragment_->Length())
+  if (!text_item.TextLength())
     return;
-  IntRect visual_rect = paint_fragment_->VisualRect();
+  const IntRect visual_rect = AsDisplayItemClient(cursor_).VisualRect();
   if (visual_rect.IsEmpty())
     return;
 
-  if (!text_fragment_->TextShapeResult() &&
+  if (!text_item.TextShapeResult() &&
       // A line break's selection tint is still visible.
-      !text_fragment_->IsLineBreak())
+      !text_item.IsLineBreak())
     return;
 
-  Paint(text_fragment_->PaintInfo(), text_fragment_->GetLayoutObject(),
-        *paint_fragment_, text_fragment_->Style(),
-        {paint_fragment_->Offset(), text_fragment_->Size()}, visual_rect,
-        text_fragment_->IsEllipsis(),
-        text_fragment_->TextType() == NGPhysicalTextFragment::kSymbolMarker,
-        paint_info, paint_offset);
-}
-
-void NGTextFragmentPainter::PaintItem(const PaintInfo& paint_info,
-                                      const PhysicalOffset& paint_offset) {
-  DCHECK(item_ && items_);
-
-  if (!item_->TextLength())
-    return;
-  IntRect visual_rect = item_->VisualRect();
-  if (visual_rect.IsEmpty())
-    return;
-
-  NGTextFragmentPaintInfo fragment_paint_info = item_->TextPaintInfo(*items_);
-  bool is_ellipsis = false;       // TODO(kojii): Implement.
-  bool is_symbol_marker = false;  // TODO(kojii): Implement.
-  Paint(fragment_paint_info, item_->GetLayoutObject(), *item_, item_->Style(),
-        item_->Rect(), visual_rect, is_ellipsis, is_symbol_marker, paint_info,
-        paint_offset);
-}
-
-void NGTextFragmentPainter::Paint(
-    const NGTextFragmentPaintInfo& fragment_paint_info,
-    const LayoutObject* layout_object,
-    const DisplayItemClient& display_item_client,
-    const ComputedStyle& style,
-    PhysicalRect box_rect,
-    const IntRect& visual_rect,
-    bool is_ellipsis,
-    bool is_symbol_marker,
-    const PaintInfo& paint_info,
-    const PhysicalOffset& paint_offset) {
-  DCHECK(layout_object);
+  const NGTextFragmentPaintInfo& fragment_paint_info =
+      GetTextFragmentPaintInfo(cursor_);
+  const LayoutObject* layout_object = text_item.GetLayoutObject();
+  const ComputedStyle& style = text_item.Style();
+  PhysicalRect box_rect = AsDisplayItemClient(cursor_).Rect();
   const Document& document = layout_object->GetDocument();
   const bool is_printing = paint_info.IsPrinting();
 
@@ -334,16 +383,9 @@
                         layout_object->IsSelected();
   base::Optional<LayoutSelectionStatus> selection_status;
   if (have_selection) {
-    if (paint_fragment_) {
-      selection_status =
-          document.GetFrame()->Selection().ComputeLayoutSelectionStatus(
-              *paint_fragment_);
-      DCHECK_LE(selection_status->start, selection_status->end);
-      have_selection = selection_status->start < selection_status->end;
-    } else {
-      // TODO(kojii): Implement without paint_fragment_
-      have_selection = false;
-    }
+    selection_status = ComputeLayoutSelectionStatus(cursor_);
+    DCHECK_LE(selection_status->start, selection_status->end);
+    have_selection = selection_status->start < selection_status->end;
   }
   if (!have_selection) {
     // When only painting the selection, don't bother to paint if there is none.
@@ -351,8 +393,7 @@
       return;
 
     // Flow controls (line break, tab, <wbr>) need only selection painting.
-    if ((text_fragment_ && text_fragment_->IsFlowControl()) ||
-        (item_ && item_->IsFlowControl()))
+    if (text_item.IsFlowControl())
       return;
   }
 
@@ -362,12 +403,13 @@
   base::Optional<DrawingRecorder> recorder;
   if (paint_info.phase != PaintPhase::kTextClip) {
     if (DrawingRecorder::UseCachedDrawingIfPossible(
-            paint_info.context, display_item_client, paint_info.phase))
+            paint_info.context, AsDisplayItemClient(cursor_), paint_info.phase))
       return;
-    recorder.emplace(paint_info.context, display_item_client, paint_info.phase);
+    recorder.emplace(paint_info.context, AsDisplayItemClient(cursor_),
+                     paint_info.phase);
   }
 
-  if (UNLIKELY(is_symbol_marker)) {
+  if (UNLIKELY(text_item.IsSymbolMarker())) {
     // The NGInlineItem of marker might be Split(). So PaintSymbol only if the
     // StartOffset is 0, or it might be painted several times.
     if (!fragment_paint_info.from) {
@@ -401,13 +443,6 @@
   DCHECK(font_data);
 
   base::Optional<GraphicsContextStateSaver> state_saver;
-  base::Optional<NGFragmentItem> text_item_buffer;
-  if (text_fragment_)
-    text_item_buffer.emplace(*text_fragment_);
-  const NGFragmentItem& text_item =
-      text_fragment_ ? text_item_buffer.value() : *item_;
-  StringView text =
-      text_fragment_ ? text_fragment_->Text() : item_->Text(*items_);
 
   // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
   // include selection and composition highlights.
@@ -418,19 +453,15 @@
   // NGPaintFragment::ComputeLocalSelectionRectForText logical so that we can
   // paint selection in same fliped dimention as NGTextPainter.
   const DocumentMarkerVector& markers_to_paint =
-      ComputeMarkersToPaint(node, is_ellipsis);
+      ComputeMarkersToPaint(node, text_item.IsEllipsis());
   if (paint_info.phase != PaintPhase::kSelection &&
       paint_info.phase != PaintPhase::kTextClip && !is_printing) {
-    PaintDocumentMarkers(context, text_item, text, markers_to_paint,
-                         box_rect.offset, style,
+    PaintDocumentMarkers(context, text_item, fragment_paint_info.text,
+                         markers_to_paint, box_rect.offset, style,
                          DocumentMarkerPaintPhase::kBackground, nullptr);
     if (have_selection) {
-      if (paint_fragment_) {
-        PaintSelection(context, *paint_fragment_, node, document, style,
-                       selection_style.fill_color, box_rect, *selection_status);
-      } else {
-        // TODO(kojii): Implement without paint_fragment_.
-      }
+      PaintSelection(context, cursor_, node, document, style,
+                     selection_style.fill_color, box_rect, *selection_status);
     }
   }
 
@@ -473,7 +504,7 @@
     if (style.TextDecorationsInEffect() != TextDecoration::kNone &&
         // Ellipsis should not have text decorations. This is not defined, but 4
         // impls do this.
-        !is_ellipsis) {
+        !text_item.IsEllipsis()) {
       PhysicalOffset local_origin = box_rect.offset;
       LayoutUnit width = box_rect.Width();
       const NGPhysicalBoxFragment* decorating_box = nullptr;
@@ -484,8 +515,8 @@
           decoration_info, box_rect.offset, local_origin, width,
           style.GetFontBaseline(), style, decorating_box_style);
 
-      NGTextDecorationOffset decoration_offset(*decoration_info.style,
-                                               text_item, decorating_box);
+      NGTextDecorationOffset decoration_offset(
+          *decoration_info.style, text_item.Style(), decorating_box);
       text_painter.PaintDecorationsExceptLineThrough(
           decoration_offset, decoration_info, paint_info,
           style.AppliedTextDecorations(), text_style,
@@ -526,9 +557,12 @@
 
   if (paint_info.phase != PaintPhase::kForeground)
     return;
-  PaintDocumentMarkers(context, text_item, text, markers_to_paint,
-                       box_rect.offset, style,
+  PaintDocumentMarkers(context, text_item, fragment_paint_info.text,
+                       markers_to_paint, box_rect.offset, style,
                        DocumentMarkerPaintPhase::kForeground, &text_painter);
 }
 
+template class NGTextFragmentPainter<NGTextPainterCursor>;
+template class NGTextFragmentPainter<NGInlineCursor>;
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h
index 760f59e..c4250c1 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h
@@ -5,6 +5,8 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_TEXT_FRAGMENT_PAINTER_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_TEXT_FRAGMENT_PAINTER_H_
 
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
 #include "third_party/blink/renderer/core/style/computed_style_constants.h"
 #include "third_party/blink/renderer/platform/geometry/layout_rect.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -14,33 +16,49 @@
 class ComputedStyle;
 class DisplayItemClient;
 class LayoutObject;
-class NGFragmentItem;
-class NGFragmentItems;
 class NGPaintFragment;
-class NGPhysicalTextFragment;
+class NGInlineCursor;
 struct NGTextFragmentPaintInfo;
 struct PaintInfo;
 struct PhysicalOffset;
 struct PhysicalRect;
 struct PhysicalSize;
 
+// The helper class for templatize |NGTextFragmentPainter|.
+// TODO(yosin): Remove |NGTextPainterCursor| once the transition to
+// |NGFragmentItem| is done. http://crbug.com/982194
+class NGTextPainterCursor {
+  STACK_ALLOCATED();
+
+ public:
+  explicit NGTextPainterCursor(const NGPaintFragment& paint_fragment)
+      : paint_fragment_(paint_fragment),
+        text_fragment_(
+            To<NGPhysicalTextFragment>(paint_fragment.PhysicalFragment())) {}
+
+  const NGPaintFragment& PaintFragment() const { return paint_fragment_; }
+  const NGPhysicalTextFragment* CurrentItem() const { return &text_fragment_; }
+
+ private:
+  const NGPaintFragment& paint_fragment_;
+  const NGPhysicalTextFragment& text_fragment_;
+};
+
 // Text fragment painter for LayoutNG. Operates on NGPhysicalTextFragments and
 // handles clipping, selection, etc. Delegates to NGTextPainter to paint the
 // text itself.
+// TODO(yosin): We should make |NGTextFragmentPainter| non-template class onnce
+// we get rid of |NGPaintFragment|.
+template <typename Cursor>
 class NGTextFragmentPainter {
   STACK_ALLOCATED();
 
  public:
-  // TODO(kojii) : Remove | NGPaintFragment | once the transition is done.
-  // crbug.com/982194
-  explicit NGTextFragmentPainter(const NGPaintFragment&);
-  NGTextFragmentPainter(const NGFragmentItem&, const NGFragmentItems&);
+  explicit NGTextFragmentPainter(const Cursor&);
 
   void Paint(const PaintInfo&, const PhysicalOffset& paint_offset);
 
  private:
-  void PaintItem(const PaintInfo&, const PhysicalOffset& paint_offset);
-
   void Paint(const NGTextFragmentPaintInfo& fragment_paint_info,
              const LayoutObject* layout_object,
              const DisplayItemClient& display_item_client,
@@ -58,13 +76,12 @@
                           const PaintInfo& paint_info,
                           const PhysicalOffset& paint_offset);
 
-  const NGPaintFragment* paint_fragment_ = nullptr;
-  const NGPhysicalTextFragment* text_fragment_ = nullptr;
-
-  const NGFragmentItem* item_ = nullptr;
-  const NGFragmentItems* items_ = nullptr;
+  const Cursor& cursor_;
 };
 
+extern template class NGTextFragmentPainter<NGTextPainterCursor>;
+extern template class NGTextFragmentPainter<NGInlineCursor>;
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_TEXT_FRAGMENT_PAINTER_H_
diff --git a/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc b/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc
index 62e4e780..87ca9fb 100644
--- a/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc
+++ b/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc
@@ -63,7 +63,8 @@
     DCHECK(animation->HasValidTarget());
 
     if (animation->NeedsToProgress(elapsed)) {
-      animation->Progress(elapsed);
+      bool interval_restart = animation->CheckAndUpdateInterval(elapsed);
+      animation->UpdateActiveState(elapsed, interval_restart);
       active_.push_back(animation);
     } else if (animation->IsContributing(elapsed)) {
       active_.push_back(animation);
@@ -74,36 +75,28 @@
 }
 
 SMILTime SMILAnimationSandwich::NextInterestingTime(
-    SMILTime document_time) const {
+    double presentation_time) const {
   SMILTime interesting_time = SMILTime::Indefinite();
-  for (const auto& it_animation : sandwich_) {
-    SVGSMILElement* animation = it_animation.Get();
-    interesting_time = std::min(interesting_time,
-                                animation->NextInterestingTime(document_time));
+  for (const auto& animation : sandwich_) {
+    interesting_time = std::min(
+        interesting_time, animation->NextInterestingTime(presentation_time));
   }
   return interesting_time;
 }
 
-SMILTime SMILAnimationSandwich::GetNextFireTime() const {
-  SMILTime earliest_fire_time = SMILTime::Unresolved();
-  for (const auto& it_animation : sandwich_) {
-    SVGSMILElement* animation = it_animation.Get();
-
-    SMILTime next_fire_time = animation->NextProgressTime();
-    if (next_fire_time.IsFinite())
-      earliest_fire_time = std::min(next_fire_time, earliest_fire_time);
+SMILTime SMILAnimationSandwich::NextProgressTime(
+    double presentation_time) const {
+  SMILTime earliest_progress_time = SMILTime::Unresolved();
+  for (const auto& animation : sandwich_) {
+    earliest_progress_time = std::min(
+        earliest_progress_time, animation->NextProgressTime(presentation_time));
   }
-  return earliest_fire_time;
+  return earliest_progress_time;
 }
 
 void SMILAnimationSandwich::UpdateSyncBases(double elapsed) {
-  for (auto& animation : active_) {
+  for (auto& animation : active_)
     animation->UpdateSyncBases();
-  }
-
-  for (auto& animation : active_) {
-    animation->UpdateNextProgressTime(elapsed);
-  }
 
   auto* it = active_.begin();
   while (it != active_.end()) {
diff --git a/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h b/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h
index 8ddd73d..0eed9c0 100644
--- a/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h
+++ b/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h
@@ -39,13 +39,8 @@
                   const Member<SVGSMILElement>& b) {
     // FIXME: This should also consider possible timing relations between the
     // elements.
-    SMILTime a_begin = a->IntervalBegin();
-    SMILTime b_begin = b->IntervalBegin();
-    // Frozen elements need to be prioritized based on their previous interval.
-    a_begin = a->IsFrozen() && elapsed_ < a_begin ? a->PreviousIntervalBegin()
-                                                  : a_begin;
-    b_begin = b->IsFrozen() && elapsed_ < b_begin ? b->PreviousIntervalBegin()
-                                                  : b_begin;
+    SMILTime a_begin = a->BeginTimeForPrioritization(elapsed_);
+    SMILTime b_begin = b->BeginTimeForPrioritization(elapsed_);
     if (a_begin == b_begin)
       return a->DocumentOrderIndex() < b->DocumentOrderIndex();
     return a_begin < b_begin;
@@ -66,8 +61,8 @@
   void UpdateSyncBases(double elapsed);
   SVGSMILElement* ApplyAnimationValues();
 
-  SMILTime NextInterestingTime(SMILTime) const;
-  SMILTime GetNextFireTime() const;
+  SMILTime NextInterestingTime(double presentation_time) const;
+  SMILTime NextProgressTime(double presentation_time) const;
 
   bool IsEmpty() { return sandwich_.IsEmpty(); }
 
diff --git a/third_party/blink/renderer/core/svg/animation/smil_time.h b/third_party/blink/renderer/core/svg/animation/smil_time.h
index 4dd9c43..40ab31c 100644
--- a/third_party/blink/renderer/core/svg/animation/smil_time.h
+++ b/third_party/blink/renderer/core/svg/animation/smil_time.h
@@ -79,16 +79,6 @@
   Origin origin_;
 };
 
-struct SMILInterval {
-  DISALLOW_NEW();
-  SMILInterval() = default;
-  SMILInterval(const SMILTime& begin, const SMILTime& end)
-      : begin(begin), end(end) {}
-
-  SMILTime begin;
-  SMILTime end;
-};
-
 inline bool operator==(const SMILTime& a, const SMILTime& b) {
   return (a.IsUnresolved() && b.IsUnresolved()) || a.Value() == b.Value();
 }
@@ -129,6 +119,32 @@
 // duration * repeatCount
 SMILTime operator*(const SMILTime&, const SMILTime&);
 
+// An interval of SMILTimes.
+// "...the begin time of the interval is included in the interval, but the end
+// time is excluded from the interval."
+// (https://www.w3.org/TR/SMIL3/smil-timing.html#q101)
+struct SMILInterval {
+  DISALLOW_NEW();
+  SMILInterval() = default;
+  SMILInterval(const SMILTime& begin, const SMILTime& end)
+      : begin(begin), end(end) {}
+
+  bool IsResolved() const { return begin.IsFinite(); }
+  bool BeginsAfter(SMILTime time) const { return time < begin; }
+  bool BeginsBefore(SMILTime time) const { return !BeginsAfter(time); }
+  bool EndsAfter(SMILTime time) const {
+    DCHECK(IsResolved());
+    return time < end;
+  }
+  bool EndsBefore(SMILTime time) const { return !EndsAfter(time); }
+  bool Contains(SMILTime time) const {
+    return BeginsBefore(time) && EndsAfter(time);
+  }
+
+  SMILTime begin;
+  SMILTime end;
+};
+
 inline bool operator!=(const SMILInterval& a, const SMILInterval& b) {
   // Compare the "raw" values since the operator!= for SMILTime always return
   // true for non-finite times.
diff --git a/third_party/blink/renderer/core/svg/animation/smil_time_container.cc b/third_party/blink/renderer/core/svg/animation/smil_time_container.cc
index adb44a8..2d681ce 100644
--- a/third_party/blink/renderer/core/svg/animation/smil_time_container.cc
+++ b/third_party/blink/renderer/core/svg/animation/smil_time_container.cc
@@ -96,8 +96,9 @@
 
   sandwich->Schedule(animation);
 
-  SMILTime next_fire_time = animation->NextProgressTime();
-  if (next_fire_time.IsFinite())
+  double latest_update = CurrentDocumentTime();
+  if (animation->IntervalBegin() <= latest_update ||
+      animation->NextProgressTime(latest_update).IsFinite())
     NotifyIntervalsChanged();
 }
 
@@ -422,31 +423,30 @@
   UpdateAnimationTimings(elapsed);
   ApplyAnimationValues(elapsed);
 
-  SMILTime earliest_fire_time = SMILTime::Unresolved();
+  SMILTime next_progress_time = SMILTime::Unresolved();
   for (auto& sandwich : scheduled_animations_) {
-    SMILTime next_fire_time = sandwich.value->GetNextFireTime();
-    if (next_fire_time.IsFinite())
-      earliest_fire_time = std::min(next_fire_time, earliest_fire_time);
+    next_progress_time =
+        std::min(next_progress_time, sandwich.value->NextProgressTime(elapsed));
   }
 
-  if (!CanScheduleFrame(earliest_fire_time))
+  if (!CanScheduleFrame(next_progress_time))
     return;
-  double delay_time = earliest_fire_time.Value() - elapsed;
+  double delay_time = next_progress_time.Value() - elapsed;
   ScheduleAnimationFrame(delay_time);
 }
 
 // A helper function to fetch the next interesting time after document_time
-SMILTime SMILTimeContainer::NextInterestingTime(SMILTime document_time) const {
-  DCHECK(document_time.IsFinite());
-  DCHECK(document_time >= 0.0);
+SMILTime SMILTimeContainer::NextInterestingTime(
+    double presentation_time) const {
+  DCHECK_GE(presentation_time, 0);
   SMILTime next_interesting_time = SMILTime::Indefinite();
-  for (const auto& entry : scheduled_animations_) {
-    const auto* sandwich = entry.value.Get();
-    SMILTime interesting_time = sandwich->NextInterestingTime(document_time);
-    next_interesting_time = std::min(next_interesting_time, interesting_time);
+  for (const auto& sandwich : scheduled_animations_) {
+    next_interesting_time =
+        std::min(next_interesting_time,
+                 sandwich.value->NextInterestingTime(presentation_time));
   }
   DCHECK(!next_interesting_time.IsFinite() ||
-         document_time < next_interesting_time);
+         presentation_time < next_interesting_time);
   return next_interesting_time;
 }
 
@@ -482,7 +482,7 @@
   } while (intervals_dirty_);
 }
 
-void SMILTimeContainer::UpdateAnimationTimings(SMILTime elapsed) {
+void SMILTimeContainer::UpdateAnimationTimings(double presentation_time) {
   DCHECK(GetDocument().IsActive());
 
 #if DCHECK_IS_ON()
@@ -499,18 +499,14 @@
 
   RemoveUnusedKeys();
 
-  // Don't update if it's a duplicate.
-  if (elapsed == latest_update_time_ && elapsed != 0.0) {
-    return;
-  }
-
   if (intervals_dirty_)
     UpdateIntervals(latest_update_time_);
 
   active_sandwiches_.ReserveCapacity(scheduled_animations_.size());
-  while (latest_update_time_ < elapsed) {
+  while (latest_update_time_ < presentation_time) {
     const SMILTime interesting_time = NextInterestingTime(latest_update_time_);
-    latest_update_time_ = std::min(elapsed, interesting_time).Value();
+    latest_update_time_ =
+        std::min<SMILTime>(presentation_time, interesting_time).Value();
 
     UpdateIntervals(latest_update_time_);
   }
diff --git a/third_party/blink/renderer/core/svg/animation/smil_time_container.h b/third_party/blink/renderer/core/svg/animation/smil_time_container.h
index 13b7c0f0..eb7e28d 100644
--- a/third_party/blink/renderer/core/svg/animation/smil_time_container.h
+++ b/third_party/blink/renderer/core/svg/animation/smil_time_container.h
@@ -116,8 +116,8 @@
   void UpdateAnimationsAndScheduleFrameIfNeeded(double elapsed);
   void RemoveUnusedKeys();
   void UpdateIntervals(SMILTime);
-  SMILTime NextInterestingTime(SMILTime) const;
-  void UpdateAnimationTimings(SMILTime elapsed);
+  SMILTime NextInterestingTime(double elapsed) const;
+  void UpdateAnimationTimings(double elapsed);
   void ApplyAnimationValues(double elapsed);
   void ServiceOnNextFrame();
   void ScheduleWakeUp(double delay_time, FrameSchedulingState);
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
index 5cc85f2..431e646 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -202,7 +202,6 @@
       fill_(kFillRemove),
       last_percent_(0),
       last_repeat_(0),
-      next_progress_time_(0),
       document_order_index_(0),
       cached_dur_(kInvalidCachedTime),
       cached_repeat_dur_(kInvalidCachedTime),
@@ -279,7 +278,6 @@
   previous_interval_ = {SMILTime::Unresolved(), SMILTime::Unresolved()};
   last_percent_ = 0;
   last_repeat_ = 0;
-  next_progress_time_ = 0;
   ResolveFirstInterval();
 }
 
@@ -619,8 +617,13 @@
   return time_container_ ? time_container_->Elapsed() : 0;
 }
 
-bool SVGSMILElement::IsFrozen() const {
-  return GetActiveState() == kFrozen;
+SMILTime SVGSMILElement::BeginTimeForPrioritization(
+    double presentation_time) const {
+  if (GetActiveState() == kFrozen) {
+    if (interval_.BeginsAfter(presentation_time))
+      return previous_interval_.begin;
+  }
+  return interval_.begin;
 }
 
 SMILTime SVGSMILElement::Dur() const {
@@ -835,9 +838,6 @@
   if (!first_interval.begin.IsUnresolved() && first_interval != interval_) {
     interval_ = first_interval;
     NotifyDependentsIntervalChanged(interval_);
-    next_progress_time_ = next_progress_time_.IsUnresolved()
-                              ? interval_.begin
-                              : std::min(next_progress_time_, interval_.begin);
 
     if (time_container_)
       time_container_->NotifyIntervalsChanged();
@@ -856,20 +856,18 @@
   return base::nullopt;
 }
 
-SMILTime SVGSMILElement::NextInterestingTime(SMILTime document_time) const {
-  DCHECK(document_time.IsFinite());
-  DCHECK(0.0 <= document_time);
-  const double dt = document_time.Value();
+SMILTime SVGSMILElement::NextInterestingTime(double presentation_time) const {
+  DCHECK_GE(presentation_time, 0);
   SMILTime next_interesting_interval_time = SMILTime::Indefinite();
-  if (dt < interval_.begin) {
+  if (interval_.BeginsAfter(presentation_time)) {
     next_interesting_interval_time = interval_.begin;
-  } else if (dt < interval_.end) {
+  } else if (interval_.EndsAfter(presentation_time)) {
     next_interesting_interval_time = interval_.end;
     SMILTime simple_duration = SimpleDuration();
     if (simple_duration.IsFinite()) {
-      unsigned next_repeat = CalculateAnimationRepeat(dt) + 1;
+      unsigned next_repeat = CalculateAnimationRepeat(presentation_time) + 1;
       SMILTime repeat_time = interval_.begin + simple_duration * next_repeat;
-      if (repeat_time.IsFinite() && dt < repeat_time) {
+      if (repeat_time.IsFinite() && presentation_time < repeat_time) {
         next_interesting_interval_time =
             std::min(next_interesting_interval_time, repeat_time);
       }
@@ -887,31 +885,27 @@
   // instance times. And the animation cannot then get a new interval
   // from that instance time.
   const float half_ms = 0.0005;
-  const SMILTime instance_time = FindInstanceTime(kBegin, dt, false) - half_ms;
-  if (dt < instance_time) {
+  const SMILTime instance_time =
+      FindInstanceTime(kBegin, presentation_time, false) - half_ms;
+  if (presentation_time < instance_time)
     return std::min(next_interesting_interval_time, instance_time);
-  }
   return next_interesting_interval_time;
 }
 
-SMILTime SVGSMILElement::NextProgressTime() const {
-  return next_progress_time_;
-}
-
 void SVGSMILElement::BeginListChanged(SMILTime event_time) {
   if (is_waiting_for_first_interval_) {
     ResolveFirstInterval();
   } else if (GetRestart() != kRestartNever) {
     SMILTime new_begin = FindInstanceTime(kBegin, event_time, true);
-    if (new_begin.IsFinite() &&
-        (interval_.end <= event_time || new_begin < interval_.begin)) {
+    if (new_begin.IsFinite() && (interval_.EndsBefore(event_time) ||
+                                 interval_.BeginsAfter(new_begin))) {
       // Begin time changed, re-resolve the interval.
       SMILTime old_begin = interval_.begin;
       interval_.end = event_time;
       interval_ = ResolveInterval(kNextInterval);
-      DCHECK(!interval_.begin.IsUnresolved());
+      DCHECK(interval_.IsResolved());
       if (interval_.begin != old_begin) {
-        if (GetActiveState() == kActive && interval_.begin > event_time) {
+        if (GetActiveState() == kActive && interval_.BeginsAfter(event_time)) {
           active_state_ = DetermineActiveState(event_time);
           if (GetActiveState() != kActive)
             EndedActiveInterval();
@@ -920,7 +914,6 @@
       }
     }
   }
-  next_progress_time_ = Elapsed();
 
   if (time_container_)
     time_container_->NotifyIntervalsChanged();
@@ -930,9 +923,9 @@
   SMILTime elapsed = Elapsed();
   if (is_waiting_for_first_interval_) {
     ResolveFirstInterval();
-  } else if (elapsed < interval_.end && interval_.begin.IsFinite()) {
+  } else if (interval_.IsResolved() && interval_.EndsAfter(elapsed)) {
     SMILTime new_end = FindInstanceTime(kEnd, interval_.begin, false);
-    if (new_end < interval_.end) {
+    if (interval_.EndsAfter(new_end)) {
       new_end = ResolveActiveEnd(interval_.begin, new_end);
       if (new_end != interval_.end) {
         interval_.end = new_end;
@@ -940,45 +933,51 @@
       }
     }
   }
-  next_progress_time_ = elapsed;
 
   if (time_container_)
     time_container_->NotifyIntervalsChanged();
 }
 
-base::Optional<SMILInterval> SVGSMILElement::CheckForNewRestartInterval(
-    double elapsed) {
+bool SVGSMILElement::CheckAndUpdateInterval(double elapsed) {
   DCHECK(!is_waiting_for_first_interval_);
-  DCHECK(elapsed >= interval_.begin);
+  DCHECK(interval_.BeginsBefore(elapsed));
 
   Restart restart = GetRestart();
   if (restart == kRestartNever)
-    return base::nullopt;
+    return false;
 
-  base::Optional<SMILInterval> modified;
-  if (elapsed < interval_.end && restart == kRestartAlways) {
+  base::Optional<SMILInterval> new_interval;
+  if (restart == kRestartAlways && interval_.EndsAfter(elapsed)) {
     SMILTime next_begin = FindInstanceTime(kBegin, interval_.begin, false);
-    if (next_begin < interval_.end) {
-      modified = interval_;
-      modified->end = next_begin;
+    if (interval_.EndsAfter(next_begin)) {
+      new_interval = interval_;
+      new_interval->end = next_begin;
     }
   }
 
-  if ((modified && elapsed >= modified->end) ||
-      (!modified && elapsed >= interval_.end)) {
-    modified = ResolveNextInterval();
+  if ((new_interval && new_interval->EndsBefore(elapsed)) ||
+      (!new_interval && interval_.EndsBefore(elapsed))) {
+    new_interval = ResolveNextInterval();
   }
 
-  return modified;
+  // Track "restarts" to handle active -> active transitions.
+  bool interval_restart = (new_interval && *new_interval != interval_);
+
+  if (new_interval) {
+    previous_interval_ = interval_;
+    interval_ = *new_interval;
+    interval_has_changed_ = true;
+  }
+  return interval_restart;
 }
 
 const SMILInterval& SVGSMILElement::GetActiveInterval(double elapsed) const {
   // If there's no current interval, return the previous interval.
-  if (!interval_.begin.IsFinite())
+  if (!interval_.IsResolved())
     return previous_interval_;
   // If there's a previous interval and the current interval hasn't begun yet,
   // return the previous interval.
-  if (previous_interval_.begin.IsFinite() && elapsed < interval_.begin)
+  if (previous_interval_.IsResolved() && interval_.BeginsAfter(elapsed))
     return previous_interval_;
   return interval_;
 }
@@ -1017,7 +1016,7 @@
   }
   DCHECK(simple_duration.IsFinite());
   const SMILInterval& active_interval = GetActiveInterval(elapsed);
-  DCHECK(active_interval.begin.IsFinite());
+  DCHECK(active_interval.IsResolved());
 
   SMILTime repeating_duration = RepeatingDuration();
   double active_time = elapsed - active_interval.begin.Value();
@@ -1044,7 +1043,7 @@
   return clampTo<float>(simple_time / simple_duration.Value());
 }
 
-SMILTime SVGSMILElement::CalculateNextProgressTime(double elapsed) const {
+SMILTime SVGSMILElement::NextProgressTime(double presentation_time) const {
   if (GetActiveState() == kActive) {
     // If duration is indefinite the value does not actually change over time.
     // Same is true for <set>.
@@ -1054,22 +1053,22 @@
       // We are supposed to do freeze semantics when repeating ends, even if the
       // element is still active.
       // Take care that we get a timer callback at that point.
-      if (elapsed < repeating_duration_end &&
-          repeating_duration_end < interval_.end &&
+      if (presentation_time < repeating_duration_end &&
+          interval_.EndsAfter(repeating_duration_end) &&
           repeating_duration_end.IsFinite())
         return repeating_duration_end;
       return interval_.end;
     }
-    return elapsed + 0.025;
+    return presentation_time + 0.025;
   }
-  return interval_.begin >= elapsed ? interval_.begin : SMILTime::Unresolved();
+  return interval_.begin >= presentation_time ? interval_.begin
+                                              : SMILTime::Unresolved();
 }
 
 SVGSMILElement::ActiveState SVGSMILElement::DetermineActiveState(
     SMILTime elapsed) const {
-  if (elapsed >= interval_.begin && elapsed < interval_.end)
+  if (interval_.Contains(elapsed))
     return kActive;
-
   return Fill() == kFillFreeze ? kFrozen : kInactive;
 }
 
@@ -1089,21 +1088,19 @@
   // Check we're connected to something.
   DCHECK(time_container_);
   // Check that we have some form of start or are prepared to find it.
-  DCHECK(is_waiting_for_first_interval_ || interval_.begin.IsFinite());
+  DCHECK(is_waiting_for_first_interval_ || interval_.IsResolved());
 
   if (!sync_base_conditions_connected_)
     ConnectSyncBaseConditions();
 
   // Check if we need updating, otherwise just return.
-  if (!interval_.begin.IsFinite()) {
+  if (!interval_.IsResolved()) {
     DCHECK_EQ(GetActiveState(), kInactive);
-    next_progress_time_ = SMILTime::Unresolved();
     return false;
   }
 
-  if (elapsed < interval_.begin) {
+  if (interval_.BeginsAfter(elapsed)) {
     DCHECK_NE(GetActiveState(), kActive);
-    next_progress_time_ = interval_.begin;
     return false;
   }
 
@@ -1130,28 +1127,9 @@
     return;
   interval_has_changed_ = false;
   NotifyDependentsIntervalChanged(interval_);
-  next_progress_time_ = next_progress_time_.IsUnresolved()
-                            ? interval_.begin
-                            : std::min(next_progress_time_, interval_.begin);
 }
 
-void SVGSMILElement::UpdateNextProgressTime(double elapsed) {
-  next_progress_time_ = CalculateNextProgressTime(elapsed);
-}
-
-void SVGSMILElement::Progress(double elapsed) {
-  base::Optional<SMILInterval> new_interval =
-      CheckForNewRestartInterval(elapsed);
-
-  // Track "restarts" to handle active -> active transitions.
-  bool interval_restart = (new_interval && *new_interval != interval_);
-
-  if (new_interval) {
-    previous_interval_ = interval_;
-    interval_ = *new_interval;
-    interval_has_changed_ = true;
-  }
-
+void SVGSMILElement::UpdateActiveState(double elapsed, bool interval_restart) {
   ActiveState old_active_state = GetActiveState();
   active_state_ = DetermineActiveState(elapsed);
 
@@ -1180,7 +1158,7 @@
 
 void SVGSMILElement::NotifyDependentsIntervalChanged(
     const SMILInterval& interval) {
-  DCHECK(interval.begin.IsFinite());
+  DCHECK(interval.IsResolved());
   // |loopBreaker| is used to avoid infinite recursions which may be caused by:
   // |notifyDependentsIntervalChanged| -> |createInstanceTimesFromSyncBase| ->
   // |add{Begin,End}Time| -> |{begin,end}TimeChanged| ->
@@ -1239,7 +1217,7 @@
 
 void SVGSMILElement::AddSyncBaseDependent(SVGSMILElement& animation) {
   sync_base_dependents_.insert(&animation);
-  if (interval_.begin.IsFinite())
+  if (interval_.IsResolved())
     animation.CreateInstanceTimesFromSyncBase(this, interval_);
 }
 
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
index 746b4f5..001c9fd 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -81,17 +81,19 @@
   SMILTime Elapsed() const;
 
   SMILTime IntervalBegin() const { return interval_.begin; }
-  SMILTime PreviousIntervalBegin() const { return previous_interval_.begin; }
+  SMILTime BeginTimeForPrioritization(double presentation_time) const;
   SMILTime SimpleDuration() const;
 
   bool NeedsToProgress(double elapsed);
-  void Progress(double elapsed);
+  // Check if the current interval is still current, and if not compute the
+  // next interval. Returns true if the interval was restarted.
+  bool CheckAndUpdateInterval(double elapsed);
+  void UpdateActiveState(double elapsed, bool interval_restart);
   void TriggerPendingEvents(double elapsed);
   void UpdateSyncBases();
-  void UpdateNextProgressTime(double elapsed);
 
-  SMILTime NextInterestingTime(SMILTime) const;
-  SMILTime NextProgressTime() const;
+  SMILTime NextInterestingTime(double elapsed) const;
+  SMILTime NextProgressTime(double elapsed) const;
   void UpdateAnimatedValue(SVGSMILElement* result_element) {
     UpdateAnimation(last_percent_, last_repeat_, result_element);
   }
@@ -102,7 +104,6 @@
   static SMILTime ParseOffsetValue(const String&);
 
   bool IsContributing(double elapsed) const;
-  bool IsFrozen() const;
 
   unsigned DocumentOrderIndex() const { return document_order_index_; }
   void SetDocumentOrderIndex(unsigned index) { document_order_index_ = index; }
@@ -191,7 +192,6 @@
   SMILTime RepeatingDuration() const;
   const SMILInterval& GetActiveInterval(double elapsed) const;
 
-  base::Optional<SMILInterval> CheckForNewRestartInterval(double elapsed);
   void BeginListChanged(SMILTime event_time);
   void EndListChanged(SMILTime event_time);
 
@@ -258,7 +258,6 @@
   ActiveState DetermineActiveState(SMILTime elapsed) const;
   float CalculateAnimationPercent(double elapsed) const;
   unsigned CalculateAnimationRepeat(double elapsed) const;
-  SMILTime CalculateNextProgressTime(double elapsed) const;
 
   Member<SVGElement> target_element_;
   Member<IdTargetObserver> target_id_observer_;
@@ -289,8 +288,6 @@
   float last_percent_;
   unsigned last_repeat_;
 
-  SMILTime next_progress_time_;
-
   Member<SMILTimeContainer> time_container_;
   unsigned document_order_index_;
 
diff --git a/third_party/blink/renderer/core/testing/dictionary_test.cc b/third_party/blink/renderer/core/testing/dictionary_test.cc
index 368c08dd..c702490 100644
--- a/third_party/blink/renderer/core/testing/dictionary_test.cc
+++ b/third_party/blink/renderer/core/testing/dictionary_test.cc
@@ -297,8 +297,11 @@
 void DictionaryTest::Trace(blink::Visitor* visitor) {
   visitor->Trace(element_member_);
   visitor->Trace(element_or_null_member_);
+  visitor->Trace(object_member_);
+  visitor->Trace(object_or_null_member_with_default_);
   visitor->Trace(double_or_string_sequence_member_);
   visitor->Trace(event_target_or_null_member_);
+  visitor->Trace(any_member_);
   visitor->Trace(callback_function_member_);
   ScriptWrappable::Trace(visitor);
 }
diff --git a/third_party/blink/renderer/core/timing/performance_long_task_timing.cc b/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
index 06d932d..73d7f79 100644
--- a/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
@@ -56,7 +56,7 @@
 
 void PerformanceLongTaskTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
   PerformanceEntry::BuildJSONValue(builder);
-  Vector<ScriptValue> attribution;
+  HeapVector<ScriptValue> attribution;
   for (unsigned i = 0; i < attribution_.size(); i++) {
     attribution.push_back(
         attribution_[i]->toJSONForBinding(builder.GetScriptState()));
diff --git a/third_party/blink/renderer/core/timing/performance_resource_timing.cc b/third_party/blink/renderer/core/timing/performance_resource_timing.cc
index 2ffba14..e503a92 100644
--- a/third_party/blink/renderer/core/timing/performance_resource_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_resource_timing.cc
@@ -358,7 +358,7 @@
   builder.AddNumber("encodedBodySize", encodedBodySize());
   builder.AddNumber("decodedBodySize", decodedBodySize());
 
-  Vector<ScriptValue> server_timing;
+  HeapVector<ScriptValue> server_timing;
   server_timing.ReserveCapacity(server_timing_.size());
   for (unsigned i = 0; i < server_timing_.size(); i++) {
     server_timing.push_back(
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc
index eabed31..1d63c7a 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -172,7 +172,7 @@
 
 void DedicatedWorker::postMessage(ScriptState* script_state,
                                   const ScriptValue& message,
-                                  Vector<ScriptValue>& transfer,
+                                  HeapVector<ScriptValue>& transfer,
                                   ExceptionState& exception_state) {
   PostMessageOptions* options = PostMessageOptions::Create();
   if (!transfer.IsEmpty())
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.h b/third_party/blink/renderer/core/workers/dedicated_worker.h
index 4e56d50..6b80c553 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker.h
+++ b/third_party/blink/renderer/core/workers/dedicated_worker.h
@@ -66,7 +66,7 @@
 
   void postMessage(ScriptState*,
                    const ScriptValue& message,
-                   Vector<ScriptValue>& transfer,
+                   HeapVector<ScriptValue>& transfer,
                    ExceptionState&);
   void postMessage(ScriptState*,
                    const ScriptValue& message,
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
index 515a989..fedd0a71 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -217,7 +217,7 @@
 
 void DedicatedWorkerGlobalScope::postMessage(ScriptState* script_state,
                                              const ScriptValue& message,
-                                             Vector<ScriptValue>& transfer,
+                                             HeapVector<ScriptValue>& transfer,
                                              ExceptionState& exception_state) {
   PostMessageOptions* options = PostMessageOptions::Create();
   if (!transfer.IsEmpty())
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 ef1d837..9aa91ebc 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
@@ -97,7 +97,7 @@
   const String name() const;
   void postMessage(ScriptState*,
                    const ScriptValue& message,
-                   Vector<ScriptValue>& transfer,
+                   HeapVector<ScriptValue>& transfer,
                    ExceptionState&);
   void postMessage(ScriptState*,
                    const ScriptValue& message,
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js b/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js
index 8298410..a309861 100644
--- a/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js
+++ b/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js
@@ -1191,12 +1191,28 @@
     const color = Timeline.TimelineUIUtils.networkCategoryColor(category);
     contentHelper.addSection(ls`Network request`, color);
 
-    const duration = request.endTime - (request.getStartTime() || -Infinity);
     if (request.url)
       contentHelper.appendElementRow(ls`URL`, Components.Linkifier.linkifyURL(request.url));
     Timeline.TimelineUIUtils._maybeAppendProductToDetails(contentHelper, badgePool, request.url);
-    if (isFinite(duration))
-      contentHelper.appendTextRow(ls`Duration`, Number.millisToString(duration, true));
+
+    // The time from queueing the request until resource processing is finished.
+    const fullDuration = request.endTime - (request.getStartTime() || -Infinity);
+    if (isFinite(fullDuration)) {
+      let textRow = Number.millisToString(fullDuration, true);
+      // The time from queueing the request until the download is finished. This
+      // corresponds to the total time reported for the request in the network tab.
+      const networkDuration = request.finishTime - request.getStartTime();
+      // The time it takes to make the resource available to the renderer process.
+      const processingDuration = request.endTime - request.finishTime;
+      if (isFinite(networkDuration) && isFinite(processingDuration)) {
+        const networkDurationStr = Number.millisToString(networkDuration, true);
+        const processingDurationStr = Number.millisToString(processingDuration, true);
+        const cacheOrNetworkLabel = request.cached() ? ls`load from cache` : ls`network transfer`;
+        textRow += ls` (${networkDurationStr} ${cacheOrNetworkLabel} + ${processingDurationStr} resource loading)`;
+      }
+      contentHelper.appendTextRow(ls`Duration`, textRow);
+    }
+
     if (request.requestMethod)
       contentHelper.appendTextRow(ls`Request Method`, request.requestMethod);
     if (typeof request.priority === 'string') {
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp b/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp
index 064f972..4d860c4 100644
--- a/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp
+++ b/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp
@@ -352,6 +352,9 @@
   <message name="IDS_DEVTOOLS_55b4b48b80795ee9b6a3220ca415786d" desc="Text in Timeline UIUtils of the Performance panel">
     Schedule Style Recalculation
   </message>
+  <message name="IDS_DEVTOOLS_571d0a86e3e15c23eb715c4e8b46b7b8" desc="Text in Timeline UIUtils of the Performance panel">
+    ''' (<ph name="NETWORKDURATIONSTR">$1s<ex>1ms</ex></ph> <ph name="CACHEORNETWORKLABEL">$2s<ex>network transfer</ex></ph> + <ph name="PROCESSINGDURATIONSTR">$3s<ex>1ms</ex></ph> resource loading)
+  </message>
   <message name="IDS_DEVTOOLS_57f06e0eceb273507ade79baf8d3a2d4" desc="Text in Timeline UIUtils of the Performance panel">
     Tap Begin
   </message>
@@ -813,6 +816,9 @@
   <message name="IDS_DEVTOOLS_d5e3345f0d0b507c8993b1ca0e0ac2c4" desc="Text in Timeline UIUtils of the Performance panel">
     First Paint
   </message>
+  <message name="IDS_DEVTOOLS_d5f967961bccf06a9eb7989d69d94a15" desc="Text in Timeline UIUtils of the Performance panel">
+    network transfer
+  </message>
   <message name="IDS_DEVTOOLS_d84fe3f1d290e4855cc0487b5ea18a4a" desc="Text in Timeline UIUtils of the Performance panel">
     Pinch Begin
   </message>
@@ -825,6 +831,9 @@
   <message name="IDS_DEVTOOLS_d97477d6d8a838ead9348185bb5b6742" desc="Text in Timeline Flame Chart Data Provider of the Performance panel">
     Thread
   </message>
+  <message name="IDS_DEVTOOLS_d97db6efa26ba3b28be1f0d597f1d759" desc="Text in Timeline UIUtils of the Performance panel">
+    load from cache
+  </message>
   <message name="IDS_DEVTOOLS_da3c710f68f0c891ecad19dcbf2ab349" desc="Text in Timeline UIUtils of the Performance panel">
     Console Time
   </message>
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index bd334a5..3e59985b 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -382,7 +382,7 @@
 }
 
 static bool IsListElement(Node* node) {
-  return IsHTMLUListElement(*node) || IsHTMLOListElement(*node) ||
+  return IsHTMLUListElement(*node) || IsA<HTMLOListElement>(*node) ||
          IsA<HTMLDListElement>(*node);
 }
 
@@ -598,7 +598,7 @@
   if (IsHTMLDivElement(*GetNode()))
     return ax::mojom::Role::kGenericContainer;
 
-  if (IsHTMLMeterElement(*GetNode()))
+  if (IsA<HTMLMeterElement>(*GetNode()))
     return ax::mojom::Role::kMeter;
 
   if (IsHTMLProgressElement(*GetNode()))
@@ -1723,7 +1723,7 @@
     return std::isfinite(*out_value);
   }
 
-  if (auto* meter = ToHTMLMeterElementOrNull(GetNode())) {
+  if (auto* meter = DynamicTo<HTMLMeterElement>(GetNode())) {
     *out_value = meter->value();
     return true;
   }
@@ -1769,7 +1769,7 @@
     return std::isfinite(*out_value);
   }
 
-  if (auto* meter = ToHTMLMeterElementOrNull(GetNode())) {
+  if (auto* meter = DynamicTo<HTMLMeterElement>(GetNode())) {
     *out_value = meter->max();
     return true;
   }
@@ -1802,7 +1802,7 @@
     return std::isfinite(*out_value);
   }
 
-  if (auto* meter = ToHTMLMeterElementOrNull(GetNode())) {
+  if (auto* meter = DynamicTo<HTMLMeterElement>(GetNode())) {
     *out_value = meter->min();
     return true;
   }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 00568b6..932e25f 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -390,7 +390,7 @@
   // ul/ol/dl type (it shouldn't be a list if aria says otherwise).
   if (NodeHasRole(node, "list") || NodeHasRole(node, "directory") ||
       (NodeHasRole(node, g_null_atom) &&
-       (IsHTMLUListElement(node) || IsHTMLOListElement(node) ||
+       (IsHTMLUListElement(node) || IsA<HTMLOListElement>(node) ||
         IsA<HTMLDListElement>(node))))
     return MakeGarbageCollected<AXList>(layout_object, *this);
 
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc
index 844223a..0dab4a1 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -865,7 +865,7 @@
 
   HeapVector<RequestInfo> request_infos;
   request_infos.resize(requests.size());
-  Vector<ScriptPromise> promises;
+  HeapVector<ScriptPromise> promises;
   promises.resize(requests.size());
   for (wtf_size_t i = 0; i < requests.size(); ++i) {
     if (!requests[i]->url().ProtocolIsInHTTPFamily()) {
diff --git a/third_party/blink/renderer/modules/geolocation/BUILD.gn b/third_party/blink/renderer/modules/geolocation/BUILD.gn
index 65a4d21..c0a79e2 100644
--- a/third_party/blink/renderer/modules/geolocation/BUILD.gn
+++ b/third_party/blink/renderer/modules/geolocation/BUILD.gn
@@ -6,18 +6,18 @@
 
 blink_modules_sources("geolocation") {
   sources = [
-    "coordinates.cc",
-    "coordinates.h",
     "geo_notifier.cc",
     "geo_notifier.h",
     "geolocation.cc",
     "geolocation.h",
+    "geolocation_coordinates.cc",
+    "geolocation_coordinates.h",
     "geolocation_error.h",
+    "geolocation_position_error.h",
     "geolocation_watchers.cc",
     "geolocation_watchers.h",
     "geoposition.h",
     "navigator_geolocation.cc",
     "navigator_geolocation.h",
-    "position_error.h",
   ]
 }
diff --git a/third_party/blink/renderer/modules/geolocation/geo_notifier.cc b/third_party/blink/renderer/modules/geolocation/geo_notifier.cc
index 1f2293b..578ab16 100644
--- a/third_party/blink/renderer/modules/geolocation/geo_notifier.cc
+++ b/third_party/blink/renderer/modules/geolocation/geo_notifier.cc
@@ -7,7 +7,7 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/modules/geolocation/geolocation.h"
-#include "third_party/blink/renderer/modules/geolocation/position_error.h"
+#include "third_party/blink/renderer/modules/geolocation/geolocation_position_error.h"
 #include "third_party/blink/renderer/modules/geolocation/position_options.h"
 #include "third_party/blink/renderer/platform/instrumentation/histogram.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -45,7 +45,7 @@
   visitor->Trace(fatal_error_);
 }
 
-void GeoNotifier::SetFatalError(PositionError* error) {
+void GeoNotifier::SetFatalError(GeolocationPositionError* error) {
   // If a fatal error has already been set, stick with it. This makes sure that
   // when permission is denied, this is the error reported, as required by the
   // spec.
@@ -67,7 +67,7 @@
   success_callback_->InvokeAndReportException(nullptr, position);
 }
 
-void GeoNotifier::RunErrorCallback(PositionError* error) {
+void GeoNotifier::RunErrorCallback(GeolocationPositionError* error) {
   if (error_callback_)
     error_callback_->InvokeAndReportException(nullptr, error);
 }
@@ -132,8 +132,8 @@
 
   if (error_callback_) {
     error_callback_->InvokeAndReportException(
-        nullptr, MakeGarbageCollected<PositionError>(PositionError::kTimeout,
-                                                     "Timeout expired"));
+        nullptr, MakeGarbageCollected<GeolocationPositionError>(
+                     GeolocationPositionError::kTimeout, "Timeout expired"));
   }
 
   DEFINE_STATIC_LOCAL(CustomCountHistogram, timeout_expired_histogram,
diff --git a/third_party/blink/renderer/modules/geolocation/geo_notifier.h b/third_party/blink/renderer/modules/geolocation/geo_notifier.h
index 2da6954..4bb380c 100644
--- a/third_party/blink/renderer/modules/geolocation/geo_notifier.h
+++ b/third_party/blink/renderer/modules/geolocation/geo_notifier.h
@@ -16,8 +16,8 @@
 namespace blink {
 
 class Geolocation;
+class GeolocationPositionError;
 class Geoposition;
-class PositionError;
 
 class GeoNotifier final : public GarbageCollectedFinalized<GeoNotifier>,
                           public NameClient {
@@ -34,7 +34,7 @@
 
   // Sets the given error as the fatal error if there isn't one yet.
   // Starts the timer with an interval of 0.
-  void SetFatalError(PositionError*);
+  void SetFatalError(GeolocationPositionError*);
 
   bool UseCachedPosition() const { return use_cached_position_; }
 
@@ -43,7 +43,7 @@
   void SetUseCachedPosition();
 
   void RunSuccessCallback(Geoposition*);
-  void RunErrorCallback(PositionError*);
+  void RunErrorCallback(GeolocationPositionError*);
 
   void StartTimer();
   void StopTimer();
@@ -83,7 +83,7 @@
   Member<V8PositionErrorCallback> error_callback_;
   Member<const PositionOptions> options_;
   Member<Timer> timer_;
-  Member<PositionError> fatal_error_;
+  Member<GeolocationPositionError> fatal_error_;
   bool use_cached_position_;
 };
 
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation.cc b/third_party/blink/renderer/modules/geolocation/geolocation.cc
index d8bc322..1ef0801 100644
--- a/third_party/blink/renderer/modules/geolocation/geolocation.cc
+++ b/third_party/blink/renderer/modules/geolocation/geolocation.cc
@@ -39,7 +39,7 @@
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/probe/core_probes.h"
-#include "third_party/blink/renderer/modules/geolocation/coordinates.h"
+#include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h"
 #include "third_party/blink/renderer/modules/geolocation/geolocation_error.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
 
@@ -55,7 +55,7 @@
 
 Geoposition* CreateGeoposition(
     const device::mojom::blink::Geoposition& position) {
-  auto* coordinates = MakeGarbageCollected<Coordinates>(
+  auto* coordinates = MakeGarbageCollected<GeolocationCoordinates>(
       position.latitude, position.longitude,
       // Lowest point on land is at approximately -400 meters.
       position.altitude > -10000., position.altitude, position.accuracy,
@@ -67,23 +67,24 @@
       ConvertSecondsToDOMTimeStamp(position.timestamp.ToDoubleT()));
 }
 
-PositionError* CreatePositionError(
+GeolocationPositionError* CreatePositionError(
     device::mojom::blink::Geoposition::ErrorCode mojom_error_code,
     const String& error) {
-  PositionError::ErrorCode error_code = PositionError::kPositionUnavailable;
+  GeolocationPositionError::ErrorCode error_code =
+      GeolocationPositionError::kPositionUnavailable;
   switch (mojom_error_code) {
     case device::mojom::blink::Geoposition::ErrorCode::PERMISSION_DENIED:
-      error_code = PositionError::kPermissionDenied;
+      error_code = GeolocationPositionError::kPermissionDenied;
       break;
     case device::mojom::blink::Geoposition::ErrorCode::POSITION_UNAVAILABLE:
-      error_code = PositionError::kPositionUnavailable;
+      error_code = GeolocationPositionError::kPositionUnavailable;
       break;
     case device::mojom::blink::Geoposition::ErrorCode::NONE:
     case device::mojom::blink::Geoposition::ErrorCode::TIMEOUT:
       NOTREACHED();
       break;
   }
-  return MakeGarbageCollected<PositionError>(error_code, error);
+  return MakeGarbageCollected<GeolocationPositionError>(error_code, error);
 }
 
 static void ReportGeolocationViolation(Document* doc) {
@@ -100,8 +101,7 @@
 }  // namespace
 
 Geolocation* Geolocation::Create(ExecutionContext* context) {
-  Geolocation* geolocation = MakeGarbageCollected<Geolocation>(context);
-  return geolocation;
+  return MakeGarbageCollected<Geolocation>(context);
 }
 
 Geolocation::Geolocation(ExecutionContext* context)
@@ -221,8 +221,8 @@
   String error_message;
   if (!GetFrame()->GetSettings()->GetAllowGeolocationOnInsecureOrigins() &&
       !GetExecutionContext()->IsSecureContext(error_message)) {
-    notifier->SetFatalError(MakeGarbageCollected<PositionError>(
-        PositionError::kPermissionDenied, error_message));
+    notifier->SetFatalError(MakeGarbageCollected<GeolocationPositionError>(
+        GeolocationPositionError::kPermissionDenied, error_message));
     return;
   }
 
@@ -231,8 +231,9 @@
           ReportOptions::kReportOnFailure, kFeaturePolicyConsoleWarning)) {
     UseCounter::Count(GetDocument(),
                       WebFeature::kGeolocationDisabledByFeaturePolicy);
-    notifier->SetFatalError(MakeGarbageCollected<PositionError>(
-        PositionError::kPermissionDenied, kFeaturePolicyErrorMessage));
+    notifier->SetFatalError(MakeGarbageCollected<GeolocationPositionError>(
+        GeolocationPositionError::kPermissionDenied,
+        kFeaturePolicyErrorMessage));
     return;
   }
 
@@ -326,7 +327,7 @@
   }
 }
 
-void Geolocation::HandleError(PositionError* error) {
+void Geolocation::HandleError(GeolocationPositionError* error) {
   DCHECK(error);
 
   DCHECK(one_shots_being_invoked_.IsEmpty());
@@ -509,8 +510,9 @@
   StopUpdating();
   // The only reason that we would fail to get a ConnectionError is if we lack
   // sufficient permission.
-  auto* error = MakeGarbageCollected<PositionError>(
-      PositionError::kPermissionDenied, kPermissionDeniedErrorMessage);
+  auto* error = MakeGarbageCollected<GeolocationPositionError>(
+      GeolocationPositionError::kPermissionDenied,
+      kPermissionDeniedErrorMessage);
   error->SetIsFatal(true);
   HandleError(error);
 }
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation.h b/third_party/blink/renderer/modules/geolocation/geolocation.h
index 6ad28ae..1316ac8 100644
--- a/third_party/blink/renderer/modules/geolocation/geolocation.h
+++ b/third_party/blink/renderer/modules/geolocation/geolocation.h
@@ -35,9 +35,9 @@
 #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
 #include "third_party/blink/renderer/core/page/page_visibility_observer.h"
 #include "third_party/blink/renderer/modules/geolocation/geo_notifier.h"
+#include "third_party/blink/renderer/modules/geolocation/geolocation_position_error.h"
 #include "third_party/blink/renderer/modules/geolocation/geolocation_watchers.h"
 #include "third_party/blink/renderer/modules/geolocation/geoposition.h"
-#include "third_party/blink/renderer/modules/geolocation/position_error.h"
 #include "third_party/blink/renderer/modules/geolocation/position_options.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -173,7 +173,7 @@
   // Sends the given error to all notifiers, unless the error is not fatal and
   // the notifier is due to receive a cached position. Clears the oneshots,
   // and also  clears the watchers if the error is fatal.
-  void HandleError(PositionError*);
+  void HandleError(GeolocationPositionError*);
 
   // Connects to the Geolocation mojo service and starts polling for updates.
   void StartUpdating(GeoNotifier*);
@@ -184,15 +184,15 @@
   void QueryNextPosition();
 
   // Attempts to obtain a position for the given notifier, either by using
-  // the cached position or by requesting one from the Geolocation.
+  // the cached position or by requesting one from the Geolocation service.
   // Sets a fatal error if permission is denied or no position can be
   // obtained.
   void StartRequest(GeoNotifier*);
 
   bool HaveSuitableCachedPosition(const PositionOptions*);
 
-  // Record whether the origin trying to access Geolocation would be allowed
-  // to access a feature that can only be accessed by secure origins.
+  // Record whether the origin trying to access Geolocation would be
+  // allowed to access a feature that can only be accessed by secure origins.
   // See https://goo.gl/Y0ZkNV
   void RecordOriginTypeAccess() const;
 
@@ -209,10 +209,10 @@
   //
   // |HandleError(error)| and |MakeSuccessCallbacks| need to clear |one_shots_|
   // (and optionally |watchers_|) before invoking the callbacks, in order to
-  // avoid clearing notifiers added by calls to Geolocation methods from the
-  // callbacks. Thus, something else needs to make the notifiers being invoked
-  // alive with wrapper-tracing because V8 GC may run during the callbacks.
-  // |one_shots_being_invoked_| and |watchers_being_invoked_| perform
+  // avoid clearing notifiers added by calls to Geolocation methods
+  // from the callbacks. Thus, something else needs to make the notifiers being
+  // invoked alive with wrapper-tracing because V8 GC may run during the
+  // callbacks. |one_shots_being_invoked_| and |watchers_being_invoked_| perform
   // wrapper-tracing.
   // TODO(https://crbug.com/796145): Remove this hack once on-stack objects
   // get supported by either of wrapper-tracing or unified GC.
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation.idl b/third_party/blink/renderer/modules/geolocation/geolocation.idl
index 8db3bd8..9330197 100644
--- a/third_party/blink/renderer/modules/geolocation/geolocation.idl
+++ b/third_party/blink/renderer/modules/geolocation/geolocation.idl
@@ -26,8 +26,7 @@
 // https://www.w3.org/TR/geolocation-API/#geolocation_interface
 [
     ActiveScriptWrappable,
-    Exposed=Window,
-    NoInterfaceObject
+    Exposed=Window
 ] interface Geolocation {
     [
         LogActivity,
@@ -51,7 +50,8 @@
 };
 
 // https://www.w3.org/TR/geolocation-API/#position-callback
-callback PositionCallback = void(Position position);
+callback PositionCallback = void(GeolocationPosition position);
 
 // https://www.w3.org/TR/geolocation-API/#error-callback
-callback PositionErrorCallback = void (PositionError positionError);
+callback PositionErrorCallback =
+    void (GeolocationPositionError positionError);
diff --git a/third_party/blink/renderer/modules/geolocation/coordinates.cc b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc
similarity index 83%
rename from third_party/blink/renderer/modules/geolocation/coordinates.cc
rename to third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc
index b30e4e69..dab1c87 100644
--- a/third_party/blink/renderer/modules/geolocation/coordinates.cc
+++ b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc
@@ -23,11 +23,11 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "third_party/blink/renderer/modules/geolocation/coordinates.h"
+#include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h"
 
 namespace blink {
 
-double Coordinates::altitude(bool& is_null) const {
+double GeolocationCoordinates::altitude(bool& is_null) const {
   if (can_provide_altitude_)
     return altitude_;
 
@@ -35,7 +35,7 @@
   return 0;
 }
 
-double Coordinates::altitudeAccuracy(bool& is_null) const {
+double GeolocationCoordinates::altitudeAccuracy(bool& is_null) const {
   if (can_provide_altitude_accuracy_)
     return altitude_accuracy_;
 
@@ -43,7 +43,7 @@
   return 0;
 }
 
-double Coordinates::heading(bool& is_null) const {
+double GeolocationCoordinates::heading(bool& is_null) const {
   if (can_provide_heading_)
     return heading_;
 
@@ -51,7 +51,7 @@
   return 0;
 }
 
-double Coordinates::speed(bool& is_null) const {
+double GeolocationCoordinates::speed(bool& is_null) const {
   if (can_provide_speed_)
     return speed_;
 
diff --git a/third_party/blink/renderer/modules/geolocation/coordinates.h b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h
similarity index 76%
rename from third_party/blink/renderer/modules/geolocation/coordinates.h
rename to third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h
index 6296150..beefc92 100644
--- a/third_party/blink/renderer/modules/geolocation/coordinates.h
+++ b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h
@@ -23,8 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_COORDINATES_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_COORDINATES_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_COORDINATES_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_COORDINATES_H_
 
 #include "third_party/blink/renderer/modules/event_modules.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -32,21 +32,21 @@
 
 namespace blink {
 
-class Coordinates : public ScriptWrappable {
+class GeolocationCoordinates : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  Coordinates(double latitude,
-              double longitude,
-              bool provides_altitude,
-              double altitude,
-              double accuracy,
-              bool provides_altitude_accuracy,
-              double altitude_accuracy,
-              bool provides_heading,
-              double heading,
-              bool provides_speed,
-              double speed)
+  GeolocationCoordinates(double latitude,
+                         double longitude,
+                         bool provides_altitude,
+                         double altitude,
+                         double accuracy,
+                         bool provides_altitude_accuracy,
+                         double altitude_accuracy,
+                         bool provides_heading,
+                         double heading,
+                         bool provides_speed,
+                         double speed)
       : latitude_(latitude),
         longitude_(longitude),
         altitude_(altitude),
@@ -84,4 +84,4 @@
 
 }  // namespace blink
 
-#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_COORDINATES_H_
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_COORDINATES_H_
diff --git a/third_party/blink/renderer/modules/geolocation/coordinates.idl b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl
similarity index 95%
rename from third_party/blink/renderer/modules/geolocation/coordinates.idl
rename to third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl
index 93bb79c..f2916d2b 100644
--- a/third_party/blink/renderer/modules/geolocation/coordinates.idl
+++ b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl
@@ -24,9 +24,8 @@
  */
 
 [
-    Exposed=Window,
-    NoInterfaceObject
-] interface Coordinates {
+    Exposed=Window
+] interface GeolocationCoordinates {
     readonly attribute double latitude;
     readonly attribute double longitude;
     readonly attribute double? altitude;
diff --git a/third_party/blink/renderer/modules/geolocation/position.idl b/third_party/blink/renderer/modules/geolocation/geolocation_position.idl
similarity index 94%
rename from third_party/blink/renderer/modules/geolocation/position.idl
rename to third_party/blink/renderer/modules/geolocation/geolocation_position.idl
index 90d4b17..bc3ba9d4 100644
--- a/third_party/blink/renderer/modules/geolocation/position.idl
+++ b/third_party/blink/renderer/modules/geolocation/geolocation_position.idl
@@ -27,9 +27,8 @@
 
 [
     Exposed=Window,
-    NoInterfaceObject,
     ImplementedAs=Geoposition
-] interface Position {
-    readonly attribute Coordinates coords;
+] interface GeolocationPosition {
+    readonly attribute GeolocationCoordinates coords;
     readonly attribute DOMTimeStamp timestamp;
 };
diff --git a/third_party/blink/renderer/modules/geolocation/position_error.h b/third_party/blink/renderer/modules/geolocation/geolocation_position_error.h
similarity index 84%
rename from third_party/blink/renderer/modules/geolocation/position_error.h
rename to third_party/blink/renderer/modules/geolocation/geolocation_position_error.h
index 5aea482..c57b902 100644
--- a/third_party/blink/renderer/modules/geolocation/position_error.h
+++ b/third_party/blink/renderer/modules/geolocation/geolocation_position_error.h
@@ -23,8 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_POSITION_ERROR_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_POSITION_ERROR_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_POSITION_ERROR_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_POSITION_ERROR_H_
 
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -32,7 +32,7 @@
 
 namespace blink {
 
-class PositionError final : public ScriptWrappable {
+class GeolocationPositionError final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
@@ -42,7 +42,7 @@
     kTimeout = 3
   };
 
-  PositionError(ErrorCode code, const String& message)
+  GeolocationPositionError(ErrorCode code, const String& message)
       : code_(code), message_(message), is_fatal_(false) {}
 
   ErrorCode code() const { return code_; }
@@ -60,4 +60,4 @@
 
 }  // namespace blink
 
-#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_POSITION_ERROR_H_
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_POSITION_ERROR_H_
diff --git a/third_party/blink/renderer/modules/geolocation/position_error.idl b/third_party/blink/renderer/modules/geolocation/geolocation_position_error.idl
similarity index 95%
rename from third_party/blink/renderer/modules/geolocation/position_error.idl
rename to third_party/blink/renderer/modules/geolocation/geolocation_position_error.idl
index 16529fa..a0f3e3b 100644
--- a/third_party/blink/renderer/modules/geolocation/position_error.idl
+++ b/third_party/blink/renderer/modules/geolocation/geolocation_position_error.idl
@@ -24,9 +24,8 @@
  */
 
 [
-    Exposed=Window,
-    NoInterfaceObject
-] interface PositionError {
+    Exposed=Window
+] interface GeolocationPositionError {
     readonly attribute unsigned short code;
     readonly attribute DOMString message;
 
diff --git a/third_party/blink/renderer/modules/geolocation/geoposition.h b/third_party/blink/renderer/modules/geolocation/geoposition.h
index 9b39b62..0559846 100644
--- a/third_party/blink/renderer/modules/geolocation/geoposition.h
+++ b/third_party/blink/renderer/modules/geolocation/geoposition.h
@@ -28,7 +28,7 @@
 
 #include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
 #include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/geolocation/coordinates.h"
+#include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -39,7 +39,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  Geoposition(Coordinates* coordinates, DOMTimeStamp timestamp)
+  Geoposition(GeolocationCoordinates* coordinates, DOMTimeStamp timestamp)
       : coordinates_(coordinates), timestamp_(timestamp) {
     DCHECK(coordinates_);
   }
@@ -50,10 +50,10 @@
   }
 
   DOMTimeStamp timestamp() const { return timestamp_; }
-  Coordinates* coords() const { return coordinates_; }
+  GeolocationCoordinates* coords() const { return coordinates_; }
 
  private:
-  Member<Coordinates> coordinates_;
+  Member<GeolocationCoordinates> coordinates_;
   DOMTimeStamp timestamp_;
 };
 
diff --git a/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc b/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc
index 352f21e5..6804f3a 100644
--- a/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc
+++ b/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc
@@ -51,9 +51,10 @@
 }
 
 Geolocation* NavigatorGeolocation::geolocation() {
-  if (!geolocation_ && GetSupplementable()->GetFrame())
+  if (!geolocation_ && GetSupplementable()->GetFrame()) {
     geolocation_ =
         Geolocation::Create(GetSupplementable()->GetFrame()->GetDocument());
+  }
   return geolocation_;
 }
 
diff --git a/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h b/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h
index c4c6984..c3f18ae 100644
--- a/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h
+++ b/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h
@@ -30,10 +30,9 @@
 class Geolocation;
 class Navigator;
 
-class NavigatorGeolocation final
-    : public GarbageCollected<NavigatorGeolocation>,
-      public Supplement<Navigator>,
-      public NameClient {
+class NavigatorGeolocation final : public GarbageCollected<Geolocation>,
+                                   public Supplement<Navigator>,
+                                   public NameClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorGeolocation);
 
  public:
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
index 0147fb81..28727631 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
@@ -179,6 +179,7 @@
   bool isFulfilled() { return is_fulfilled_; }
   bool isRejected() { return is_rejected_; }
   ScriptValue argument() { return saved_arg_; }
+  void Trace(blink::Visitor* visitor) { visitor->Trace(saved_arg_); }
 
  private:
   class MyScriptFunction : public ScriptFunction {
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni
index 6209ed07..be37229 100644
--- a/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -163,10 +163,10 @@
           "gamepad/gamepad_haptic_actuator.idl",
           "gamepad/gamepad_list.idl",
           "gamepad/gamepad_pose.idl",
-          "geolocation/coordinates.idl",
           "geolocation/geolocation.idl",
-          "geolocation/position.idl",
-          "geolocation/position_error.idl",
+          "geolocation/geolocation_coordinates.idl",
+          "geolocation/geolocation_position.idl",
+          "geolocation/geolocation_position_error.idl",
           "hid/hid.idl",
           "hid/hid_collection_info.idl",
           "hid/hid_connection_event.idl",
diff --git a/third_party/blink/renderer/modules/nfc/nfc_reader.cc b/third_party/blink/renderer/modules/nfc/nfc_reader.cc
index 1cc7e8cb..d2aec42 100644
--- a/third_party/blink/renderer/modules/nfc/nfc_reader.cc
+++ b/third_party/blink/renderer/modules/nfc/nfc_reader.cc
@@ -26,7 +26,11 @@
 }
 
 NFCReader::NFCReader(ExecutionContext* context)
-    : ContextLifecycleObserver(context) {}
+    : ContextLifecycleObserver(context) {
+  // Call GetNFCProxy to create a proxy. This guarantees no allocation will
+  // be needed when calling HasPendingActivity later during gc tracing.
+  GetNfcProxy();
+}
 
 NFCReader::~NFCReader() = default;
 
diff --git a/third_party/blink/renderer/modules/payments/payment_instruments.cc b/third_party/blink/renderer/modules/payments/payment_instruments.cc
index 533f068d..2e30013c0 100644
--- a/third_party/blink/renderer/modules/payments/payment_instruments.cc
+++ b/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -124,7 +124,10 @@
   bool has_name() const { return has_name_; }
   const String& name() const { return name_; }
 
-  void Trace(blink::Visitor* visitor) { visitor->Trace(icons_); }
+  void Trace(blink::Visitor* visitor) {
+    visitor->Trace(icons_);
+    visitor->Trace(capabilities_);
+  }
 
  private:
   bool has_icons_;
diff --git a/third_party/blink/renderer/modules/payments/payment_response_test.cc b/third_party/blink/renderer/modules/payments/payment_response_test.cc
index 3892841..899d01b 100644
--- a/third_party/blink/renderer/modules/payments/payment_response_test.cc
+++ b/third_party/blink/renderer/modules/payments/payment_response_test.cc
@@ -42,7 +42,9 @@
                ScriptPromise(ScriptState*,
                              const PaymentValidationErrors* errorFields));
 
-  void Trace(blink::Visitor* visitor) override {}
+  void Trace(blink::Visitor* visitor) override {
+    visitor->Trace(dummy_promise_);
+  }
 
  private:
   ScriptPromise dummy_promise_;
diff --git a/third_party/blink/renderer/modules/permissions/permissions.cc b/third_party/blink/renderer/modules/permissions/permissions.cc
index c40cfbb..1a5b838 100644
--- a/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -248,7 +248,7 @@
 
 ScriptPromise Permissions::requestAll(
     ScriptState* script_state,
-    const Vector<ScriptValue>& raw_permissions,
+    const HeapVector<ScriptValue>& raw_permissions,
     ExceptionState& exception_state) {
   Vector<PermissionDescriptorPtr> internal_permissions;
   Vector<int> caller_index_to_internal_index;
diff --git a/third_party/blink/renderer/modules/permissions/permissions.h b/third_party/blink/renderer/modules/permissions/permissions.h
index d17ffd9..66260d0 100644
--- a/third_party/blink/renderer/modules/permissions/permissions.h
+++ b/third_party/blink/renderer/modules/permissions/permissions.h
@@ -26,7 +26,7 @@
   ScriptPromise request(ScriptState*, const ScriptValue&, ExceptionState&);
   ScriptPromise revoke(ScriptState*, const ScriptValue&, ExceptionState&);
   ScriptPromise requestAll(ScriptState*,
-                           const Vector<ScriptValue>&,
+                           const HeapVector<ScriptValue>&,
                            ExceptionState&);
 
  private:
diff --git a/third_party/blink/renderer/modules/scheduler/scheduler.cc b/third_party/blink/renderer/modules/scheduler/scheduler.cc
index 3a82fa8..6ea0d57 100644
--- a/third_party/blink/renderer/modules/scheduler/scheduler.cc
+++ b/third_party/blink/renderer/modules/scheduler/scheduler.cc
@@ -79,7 +79,7 @@
 
 Task* Scheduler::postTask(V8Function* callback_function,
                           SchedulerPostTaskOptions* options,
-                          const Vector<ScriptValue>& args) {
+                          const HeapVector<ScriptValue>& args) {
   TaskQueue* task_queue = getTaskQueue(AtomicString(options->priority()));
   if (!task_queue)
     return nullptr;
diff --git a/third_party/blink/renderer/modules/scheduler/scheduler.h b/third_party/blink/renderer/modules/scheduler/scheduler.h
index ad55aef..436b2ab 100644
--- a/third_party/blink/renderer/modules/scheduler/scheduler.h
+++ b/third_party/blink/renderer/modules/scheduler/scheduler.h
@@ -54,7 +54,7 @@
   // documents, this returns nullptr.
   Task* postTask(V8Function*,
                  SchedulerPostTaskOptions*,
-                 const Vector<ScriptValue>& args);
+                 const HeapVector<ScriptValue>& args);
 
   // Callbacks invoked by TaskQueues when they run scheduled tasks.
   void OnTaskStarted(TaskQueue*, Task*);
diff --git a/third_party/blink/renderer/modules/scheduler/task.cc b/third_party/blink/renderer/modules/scheduler/task.cc
index f55ed74c..9863768 100644
--- a/third_party/blink/renderer/modules/scheduler/task.cc
+++ b/third_party/blink/renderer/modules/scheduler/task.cc
@@ -20,7 +20,7 @@
 Task::Task(TaskQueue* task_queue,
            ExecutionContext* context,
            V8Function* callback,
-           const Vector<ScriptValue>& args,
+           const HeapVector<ScriptValue>& args,
            base::TimeDelta delay)
     : ContextLifecycleObserver(context),
       status_(Status::kPending),
@@ -39,6 +39,7 @@
 void Task::Trace(Visitor* visitor) {
   visitor->Trace(task_queue_);
   visitor->Trace(callback_);
+  visitor->Trace(arguments_);
   visitor->Trace(result_value_);
   visitor->Trace(result_promise_);
   visitor->Trace(exception_);
diff --git a/third_party/blink/renderer/modules/scheduler/task.h b/third_party/blink/renderer/modules/scheduler/task.h
index 53e4e1c..328eaa4 100644
--- a/third_party/blink/renderer/modules/scheduler/task.h
+++ b/third_party/blink/renderer/modules/scheduler/task.h
@@ -32,7 +32,7 @@
   Task(TaskQueue*,
        ExecutionContext*,
        V8Function*,
-       const Vector<ScriptValue>& args,
+       const HeapVector<ScriptValue>& args,
        base::TimeDelta delay);
 
   // Task IDL Interface.
@@ -84,7 +84,7 @@
   TaskHandle task_handle_;
   Member<TaskQueue> task_queue_;
   Member<V8Function> callback_;
-  Vector<ScriptValue> arguments_;
+  HeapVector<ScriptValue> arguments_;
   const base::TimeDelta delay_;
   // Only set if |delay_| > 0 since Now() can be somewhat expensive. This
   // optimizes the case where there is no delay, which we expect to be the
diff --git a/third_party/blink/renderer/modules/scheduler/task_queue.cc b/third_party/blink/renderer/modules/scheduler/task_queue.cc
index 6e343f1..32ceb18 100644
--- a/third_party/blink/renderer/modules/scheduler/task_queue.cc
+++ b/third_party/blink/renderer/modules/scheduler/task_queue.cc
@@ -54,7 +54,7 @@
 
 Task* TaskQueue::postTask(V8Function* function,
                           TaskQueuePostTaskOptions* options,
-                          const Vector<ScriptValue>& args) {
+                          const HeapVector<ScriptValue>& args) {
   // |task_runner_| will be nullptr when the context is destroyed, which
   // prevents us from scheduling tasks for detached documents.
   if (!task_runner_)
diff --git a/third_party/blink/renderer/modules/scheduler/task_queue.h b/third_party/blink/renderer/modules/scheduler/task_queue.h
index 0c7d70e..b926c68 100644
--- a/third_party/blink/renderer/modules/scheduler/task_queue.h
+++ b/third_party/blink/renderer/modules/scheduler/task_queue.h
@@ -51,7 +51,7 @@
   // returns nullptr.
   Task* postTask(V8Function*,
                  TaskQueuePostTaskOptions*,
-                 const Vector<ScriptValue>& args);
+                 const HeapVector<ScriptValue>& args);
 
   // Move the task from its current TaskQueue to this one. For pending
   // non-delayed tasks, the task is enqueued at the end of this TaskQueue. For
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker.cc b/third_party/blink/renderer/modules/service_worker/service_worker.cc
index 66703e1..501bb44 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker.cc
@@ -56,7 +56,7 @@
 
 void ServiceWorker::postMessage(ScriptState* script_state,
                                 const ScriptValue& message,
-                                Vector<ScriptValue>& transfer,
+                                HeapVector<ScriptValue>& transfer,
                                 ExceptionState& exception_state) {
   PostMessageOptions* options = PostMessageOptions::Create();
   if (!transfer.IsEmpty())
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 13e6d1d..4d6385e 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker.h
@@ -55,7 +55,7 @@
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(ServiceWorker);
   USING_PRE_FINALIZER(ServiceWorker, Dispose);
-  
+
  public:
   static ServiceWorker* From(ExecutionContext*,
                              mojom::blink::ServiceWorkerObjectInfoPtr);
@@ -80,7 +80,7 @@
 
   void postMessage(ScriptState*,
                    const ScriptValue& message,
-                   Vector<ScriptValue>& transfer,
+                   HeapVector<ScriptValue>& transfer,
                    ExceptionState&);
   void postMessage(ScriptState*,
                    const ScriptValue& message,
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_client.cc b/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
index 8a8e121d..297f47b 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
@@ -86,7 +86,7 @@
 
 void ServiceWorkerClient::postMessage(ScriptState* script_state,
                                       const ScriptValue& message,
-                                      Vector<ScriptValue>& transfer,
+                                      HeapVector<ScriptValue>& transfer,
                                       ExceptionState& exception_state) {
   PostMessageOptions* options = PostMessageOptions::Create();
   if (!transfer.IsEmpty())
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_client.h b/third_party/blink/renderer/modules/service_worker/service_worker_client.h
index 0a148390..b44ef1c 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_client.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_client.h
@@ -36,7 +36,7 @@
   String lifecycleState() const;
   void postMessage(ScriptState*,
                    const ScriptValue& message,
-                   Vector<ScriptValue>& transfer,
+                   HeapVector<ScriptValue>& transfer,
                    ExceptionState&);
   void postMessage(ScriptState*,
                    const ScriptValue& message,
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc b/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
index 4fff53a..a89c3e2 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
@@ -46,6 +46,7 @@
 
   size_t CallCount() { return call_count_; }
   ScriptValue Arg() { return arg_; }
+  void Trace(blink::Visitor* visitor) { visitor->Trace(arg_); }
 
  private:
   size_t call_count_;
diff --git a/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc b/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
index 27c599799..46ad05e 100644
--- a/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
+++ b/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
@@ -87,9 +87,9 @@
   auto task_runner = context->GetTaskRunner(TaskType::kMiscPlatformAPI);
 
   BarcodeDetectorStatics::From(context)->CreateBarcodeDetection(
-      mojo::MakeRequest(&service_, task_runner),
+      service_.BindNewPipeAndPassReceiver(task_runner),
       std::move(barcode_detector_options));
-  service_.set_connection_error_handler(
+  service_.set_disconnect_handler(
       WTF::Bind(&BarcodeDetector::OnConnectionError, WrapWeakPersistent(this)));
 }
 
diff --git a/third_party/blink/renderer/modules/shapedetection/barcode_detector.h b/third_party/blink/renderer/modules/shapedetection/barcode_detector.h
index 775a513..98a324a 100644
--- a/third_party/blink/renderer/modules/shapedetection/barcode_detector.h
+++ b/third_party/blink/renderer/modules/shapedetection/barcode_detector.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_BARCODE_DETECTOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_BARCODE_DETECTOR_H_
 
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/shape_detection/public/mojom/barcodedetection.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
@@ -44,7 +45,7 @@
 
   void OnConnectionError();
 
-  shape_detection::mojom::blink::BarcodeDetectionPtr service_;
+  mojo::Remote<shape_detection::mojom::blink::BarcodeDetection> service_;
 
   HeapHashSet<Member<ScriptPromiseResolver>> detect_requests_;
 };
diff --git a/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc b/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc
index a2f36614..6257552 100644
--- a/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc
+++ b/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc
@@ -34,10 +34,11 @@
 BarcodeDetectorStatics::~BarcodeDetectorStatics() = default;
 
 void BarcodeDetectorStatics::CreateBarcodeDetection(
-    shape_detection::mojom::blink::BarcodeDetectionRequest request,
+    mojo::PendingReceiver<shape_detection::mojom::blink::BarcodeDetection>
+        receiver,
     shape_detection::mojom::blink::BarcodeDetectorOptionsPtr options) {
   EnsureServiceConnection();
-  service_->CreateBarcodeDetection(std::move(request), std::move(options));
+  service_->CreateBarcodeDetection(std::move(receiver), std::move(options));
 }
 
 ScriptPromise BarcodeDetectorStatics::EnumerateSupportedFormats(
diff --git a/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h b/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h
index 0689a11..4baa785f 100644
--- a/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h
+++ b/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h
@@ -33,7 +33,7 @@
   ~BarcodeDetectorStatics();
 
   void CreateBarcodeDetection(
-      shape_detection::mojom::blink::BarcodeDetectionRequest,
+      mojo::PendingReceiver<shape_detection::mojom::blink::BarcodeDetection>,
       shape_detection::mojom::blink::BarcodeDetectorOptionsPtr);
   ScriptPromise EnumerateSupportedFormats(ScriptState*);
 
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc b/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
index d8d85d1..776d50e 100644
--- a/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
+++ b/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
@@ -347,7 +347,7 @@
 void SQLTransaction::executeSql(
     ScriptState* script_state,
     const String& sql_statement,
-    const base::Optional<Vector<ScriptValue>>& arguments,
+    const base::Optional<HeapVector<ScriptValue>>& arguments,
     V8SQLStatementCallback* callback,
     V8SQLStatementErrorCallback* callback_error,
     ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_transaction.h b/third_party/blink/renderer/modules/webdatabase/sql_transaction.h
index 916d3f1..040e059 100644
--- a/third_party/blink/renderer/modules/webdatabase/sql_transaction.h
+++ b/third_party/blink/renderer/modules/webdatabase/sql_transaction.h
@@ -161,7 +161,7 @@
   void executeSql(ScriptState*, const String& sql_statement, ExceptionState&);
   void executeSql(ScriptState*,
                   const String& sql_statement,
-                  const base::Optional<Vector<ScriptValue>>& arguments,
+                  const base::Optional<HeapVector<ScriptValue>>& arguments,
                   V8SQLStatementCallback*,
                   V8SQLStatementErrorCallback*,
                   ExceptionState&);
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
index 00e91fc..f6533df 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
@@ -164,7 +164,7 @@
   return String(name.get(), static_cast<uint32_t>(length));
 }
 
-base::Optional<Vector<ScriptValue>>
+base::Optional<HeapVector<ScriptValue>>
 WebGL2ComputeRenderingContextBase::getProgramResource(
     ScriptState* script_state,
     WebGLProgram* program,
@@ -229,7 +229,7 @@
 
   // Interpret the returned values and construct the result array. The type of
   // each array element is the natural type for the requested property.
-  Vector<ScriptValue> result;
+  HeapVector<ScriptValue> result;
   wtf_size_t auxiliary_param_index = 0;
   wtf_size_t extended_param_index = auxiliary_params.size();
   for (GLenum prop : props) {
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
index c120a67..3af9eee 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
@@ -32,7 +32,7 @@
   String getProgramResourceName(WebGLProgram*,
                                 GLenum program_interface,
                                 GLuint index);
-  base::Optional<Vector<ScriptValue>> getProgramResource(
+  base::Optional<HeapVector<ScriptValue>> getProgramResource(
       ScriptState*,
       WebGLProgram*,
       GLenum program_interface,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
index 7d6a0eb..87bfcf4 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -103,7 +103,7 @@
   return GPUBuffer::Create(this, descriptor);
 }
 
-WTF::Vector<ScriptValue> GPUDevice::createBufferMapped(
+HeapVector<ScriptValue> GPUDevice::createBufferMapped(
     ScriptState* script_state,
     const GPUBufferDescriptor* descriptor,
     ExceptionState& exception_state) {
@@ -115,7 +115,7 @@
   v8::Isolate* isolate = script_state->GetIsolate();
   v8::Local<v8::Object> creation_context = script_state->GetContext()->Global();
 
-  return WTF::Vector<ScriptValue>({
+  return HeapVector<ScriptValue>({
       ScriptValue(script_state, ToV8(gpu_buffer, creation_context, isolate)),
       ScriptValue(script_state, ToV8(array_buffer, creation_context, isolate)),
   });
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.h b/third_party/blink/renderer/modules/webgpu/gpu_device.h
index 436c03c..48836ea6 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -68,7 +68,7 @@
   GPUAdapter* adapter() const;
 
   GPUBuffer* createBuffer(const GPUBufferDescriptor* descriptor);
-  WTF::Vector<ScriptValue> createBufferMapped(
+  HeapVector<ScriptValue> createBufferMapped(
       ScriptState* script_state,
       const GPUBufferDescriptor* descriptor,
       ExceptionState& exception_state);
diff --git a/third_party/blink/renderer/modules/xr/xr.cc b/third_party/blink/renderer/modules/xr/xr.cc
index 7a66e50..f869a3d 100644
--- a/third_party/blink/renderer/modules/xr/xr.cc
+++ b/third_party/blink/renderer/modules/xr/xr.cc
@@ -129,7 +129,7 @@
 
 template <typename Fn>
 XRSessionFeatureSet ParseRequestedFeatures(
-    const WTF::Vector<ScriptValue>& features,
+    const HeapVector<ScriptValue>& features,
     XRSession::SessionMode session_mode,
     Fn&& error_fn) {
   XRSessionFeatureSet result;
diff --git a/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc b/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc
index 798b4d2..83ebb3c 100644
--- a/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc
+++ b/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc
@@ -73,7 +73,10 @@
 bool V8DOMWrapper::IsWrapper(v8::Isolate* isolate, v8::Local<v8::Value> value) {
   if (value.IsEmpty() || !value->IsObject())
     return false;
+
   v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
+  if (!object->IsApiWrapper())
+    return false;
 
   if (object->InternalFieldCount() < kV8DefaultWrapperInternalFieldCount)
     return false;
@@ -89,7 +92,10 @@
 bool V8DOMWrapper::HasInternalFieldsSet(v8::Local<v8::Value> value) {
   if (value.IsEmpty() || !value->IsObject())
     return false;
+
   v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
+  if (!object->IsApiWrapper())
+    return false;
 
   if (object->InternalFieldCount() < kV8DefaultWrapperInternalFieldCount)
     return false;
diff --git a/third_party/blink/renderer/platform/instrumentation/instance_counters.h b/third_party/blink/renderer/platform/instrumentation/instance_counters.h
index 23867b96..6a34431 100644
--- a/third_party/blink/renderer/platform/instrumentation/instance_counters.h
+++ b/third_party/blink/renderer/platform/instrumentation/instance_counters.h
@@ -48,7 +48,6 @@
   V(MediaKeys)                     \
   V(Node)                          \
   V(Resource)                      \
-  V(ScriptPromise)                 \
   V(ContextLifecycleStateObserver) \
   V(V8PerContextData)              \
   V(WorkerGlobalScope)             \
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index c9de5d29..77f06fe 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -322,14 +322,15 @@
     // TODO(domfarolino): Stop storing ResourceRequest's referrer as a header
     // and store it elsewhere. See https://crbug.com/850813.
     request.SetHttpReferrer(SecurityPolicy::GenerateReferrer(
-        referrer_policy_to_use, request.Url(), referrer_to_use));
+        referrer_policy_to_use, request.RequestorOrigin(), request.Url(),
+        referrer_to_use));
   } else {
     // In the case of stale requests that are being revalidated, these requests
     // will already have their HttpReferrer set, and we will end up here. We
     // won't regenerate the referrer, but instead check that it's still correct.
-    CHECK_EQ(SecurityPolicy::GenerateReferrer(request.GetReferrerPolicy(),
-                                              request.Url(),
-                                              request.ReferrerString())
+    CHECK_EQ(SecurityPolicy::GenerateReferrer(
+                 request.GetReferrerPolicy(), request.RequestorOrigin(),
+                 request.Url(), request.ReferrerString())
                  .referrer,
              request.HttpReferrer());
   }
@@ -1792,8 +1793,7 @@
 
   if (scoped_refptr<ResourceTimingInfo> info =
           resource_timing_info_map_.Take(resource)) {
-    if (resource->GetResponse().IsHTTP() &&
-        resource->GetResponse().HttpStatusCode() < 400) {
+    if (resource->GetResponse().IsHTTP()) {
       info->SetInitialURL(resource->GetResourceRequest()
                                   .GetInitialUrlForResourceTiming()
                                   .IsNull()
diff --git a/third_party/blink/renderer/platform/weborigin/security_policy.cc b/third_party/blink/renderer/platform/weborigin/security_policy.cc
index 28062e71..c2e809c 100644
--- a/third_party/blink/renderer/platform/weborigin/security_policy.cc
+++ b/third_party/blink/renderer/platform/weborigin/security_policy.cc
@@ -103,8 +103,11 @@
   return !url_is_secure_url;
 }
 
+// When making changes to this method that affect the return Referrer, also
+// update net::URLRequestJob::ComputeReferrerForPolicy accordingly.
 Referrer SecurityPolicy::GenerateReferrer(
     network::mojom::ReferrerPolicy referrer_policy,
+    scoped_refptr<const SecurityOrigin> origin,
     const KURL& url,
     const String& referrer) {
   network::mojom::ReferrerPolicy referrer_policy_no_default =
@@ -127,50 +130,49 @@
     case network::mojom::ReferrerPolicy::kAlways:
       return Referrer(referrer, referrer_policy_no_default);
     case network::mojom::ReferrerPolicy::kOrigin: {
-      String origin = SecurityOrigin::Create(referrer_url)->ToString();
+      String referrer_origin_string =
+          SecurityOrigin::Create(referrer_url)->ToString();
       // A security origin is not a canonical URL as it lacks a path. Add /
       // to turn it into a canonical URL we can use as referrer.
-      return Referrer(origin + "/", referrer_policy_no_default);
+      return Referrer(referrer_origin_string + "/", referrer_policy_no_default);
     }
     case network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin: {
-      scoped_refptr<const SecurityOrigin> referrer_origin =
-          SecurityOrigin::Create(referrer_url);
+      String referrer_origin_string =
+          SecurityOrigin::Create(referrer_url)->ToString();
       scoped_refptr<const SecurityOrigin> url_origin =
           SecurityOrigin::Create(url);
-      if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
-        String origin = referrer_origin->ToString();
-        return Referrer(origin + "/", referrer_policy_no_default);
+      if (!url_origin->IsSameSchemeHostPort(origin.get())) {
+        return Referrer(referrer_origin_string + "/",
+                        referrer_policy_no_default);
       }
       break;
     }
     case network::mojom::ReferrerPolicy::kSameOrigin: {
-      scoped_refptr<const SecurityOrigin> referrer_origin =
-          SecurityOrigin::Create(referrer_url);
       scoped_refptr<const SecurityOrigin> url_origin =
           SecurityOrigin::Create(url);
-      if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
+      if (!url_origin->IsSameSchemeHostPort(origin.get())) {
         return Referrer(Referrer::NoReferrer(), referrer_policy_no_default);
       }
       return Referrer(referrer, referrer_policy_no_default);
     }
     case network::mojom::ReferrerPolicy::kStrictOrigin: {
-      String origin = SecurityOrigin::Create(referrer_url)->ToString();
+      String referrer_origin_string =
+          SecurityOrigin::Create(referrer_url)->ToString();
       return Referrer(ShouldHideReferrer(url, referrer_url)
                           ? Referrer::NoReferrer()
-                          : origin + "/",
+                          : referrer_origin_string + "/",
                       referrer_policy_no_default);
     }
     case network::mojom::ReferrerPolicy::
         kNoReferrerWhenDowngradeOriginWhenCrossOrigin: {
-      scoped_refptr<const SecurityOrigin> referrer_origin =
-          SecurityOrigin::Create(referrer_url);
+      String referrer_origin_string =
+          SecurityOrigin::Create(referrer_url)->ToString();
       scoped_refptr<const SecurityOrigin> url_origin =
           SecurityOrigin::Create(url);
-      if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
-        String origin = referrer_origin->ToString();
+      if (!url_origin->IsSameSchemeHostPort(origin.get())) {
         return Referrer(ShouldHideReferrer(url, referrer_url)
                             ? Referrer::NoReferrer()
-                            : origin + "/",
+                            : referrer_origin_string + "/",
                         referrer_policy_no_default);
       }
       break;
diff --git a/third_party/blink/renderer/platform/weborigin/security_policy.h b/third_party/blink/renderer/platform/weborigin/security_policy.h
index cb4e4bd..b04f73ad0 100644
--- a/third_party/blink/renderer/platform/weborigin/security_policy.h
+++ b/third_party/blink/renderer/platform/weborigin/security_policy.h
@@ -71,6 +71,7 @@
   // navigation to a given URL. If the referrer returned is empty, the
   // referrer header should be omitted.
   static Referrer GenerateReferrer(network::mojom::ReferrerPolicy,
+                                   scoped_refptr<const SecurityOrigin> origin,
                                    const KURL&,
                                    const String& referrer);
 
diff --git a/third_party/blink/renderer/platform/weborigin/security_policy_test.cc b/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
index 32414fa..5794e396 100644
--- a/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
+++ b/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
@@ -40,10 +40,12 @@
 
 TEST(SecurityPolicyTest, EmptyReferrerForUnauthorizedScheme) {
   const KURL example_http_url = KURL("http://example.com/");
+  const String chrome_url = String::FromUTF8("chrome://somepage/");
+  scoped_refptr<const SecurityOrigin> origin =
+      SecurityOrigin::CreateFromString(chrome_url);
   EXPECT_TRUE(String() == SecurityPolicy::GenerateReferrer(
-                              network::mojom::ReferrerPolicy::kAlways,
-                              example_http_url,
-                              String::FromUTF8("chrome://somepage/"))
+                              network::mojom::ReferrerPolicy::kAlways, origin,
+                              example_http_url, chrome_url)
                               .referrer);
 }
 
@@ -51,14 +53,16 @@
   const KURL example_http_url = KURL("http://example.com/");
   const String foobar_url = String::FromUTF8("foobar://somepage/");
   const String foobar_scheme = String::FromUTF8("foobar");
+  scoped_refptr<const SecurityOrigin> origin =
+      SecurityOrigin::CreateFromString(foobar_url);
 
   EXPECT_EQ(String(), SecurityPolicy::GenerateReferrer(
-                          network::mojom::ReferrerPolicy::kAlways,
+                          network::mojom::ReferrerPolicy::kAlways, origin,
                           example_http_url, foobar_url)
                           .referrer);
   SchemeRegistry::RegisterURLSchemeAsAllowedForReferrer(foobar_scheme);
   EXPECT_EQ(foobar_url, SecurityPolicy::GenerateReferrer(
-                            network::mojom::ReferrerPolicy::kAlways,
+                            network::mojom::ReferrerPolicy::kAlways, origin,
                             example_http_url, foobar_url)
                             .referrer);
   SchemeRegistry::RemoveURLSchemeAsAllowedForReferrer(foobar_scheme);
@@ -80,6 +84,7 @@
   struct TestCase {
     network::mojom::ReferrerPolicy policy;
     const char* referrer;
+    scoped_refptr<const SecurityOrigin> origin;
     const char* destination;
     const char* expected;
   };
@@ -87,10 +92,16 @@
   const char kInsecureURLA[] = "http://a.test/path/to/file.html";
   const char kInsecureURLB[] = "http://b.test/path/to/file.html";
   const char kInsecureOriginA[] = "http://a.test/";
+  scoped_refptr<const SecurityOrigin> insecure_origin_a =
+      SecurityOrigin::CreateFromString(kInsecureOriginA);
 
   const char kSecureURLA[] = "https://a.test/path/to/file.html";
   const char kSecureURLB[] = "https://b.test/path/to/file.html";
   const char kSecureOriginA[] = "https://a.test/";
+  scoped_refptr<const SecurityOrigin> secure_origin_a =
+      SecurityOrigin::CreateFromString(kSecureOriginA);
+  scoped_refptr<const SecurityOrigin> cross_origin =
+      SecurityOrigin::CreateUniqueOpaque();
 
   const char kBlobURL[] =
       "blob:http://a.test/b3aae9c8-7f90-440d-8d7c-43aa20d72fde";
@@ -98,146 +109,159 @@
 
   TestCase inputs[] = {
       // HTTP -> HTTP: Same Origin
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kInsecureURLA,
-       kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA, kInsecureURLA,
-       kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
+       insecure_origin_a, kInsecureURLA, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA,
+       insecure_origin_a, kInsecureURLA, kInsecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kInsecureURLA,
-       kInsecureURLA, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, kInsecureURLA,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA, kInsecureURLA,
-       kInsecureOriginA},
+       insecure_origin_a, kInsecureURLA, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, insecure_origin_a,
+       kInsecureURLA, nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA,
+       insecure_origin_a, kInsecureURLA, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kInsecureURLA,
-       kInsecureURLA, kInsecureURLA},
+       insecure_origin_a, kInsecureURLA, kInsecureURLA},
       {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA,
-       kInsecureURLA, kInsecureURLA},
+       insecure_origin_a, kInsecureURLA, kInsecureURLA},
       {network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
-       kInsecureURLA, kInsecureOriginA},
+       insecure_origin_a, kInsecureURLA, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kInsecureURLA, kInsecureURLA, kInsecureURLA},
+       kInsecureURLA, insecure_origin_a, kInsecureURLA, kInsecureURLA},
 
       // HTTP -> HTTP: Cross Origin
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kInsecureURLB,
-       kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA, kInsecureURLB,
-       kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
+       insecure_origin_a, kInsecureURLB, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA,
+       insecure_origin_a, kInsecureURLB, kInsecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kInsecureURLA,
-       kInsecureURLB, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, kInsecureURLB,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA, kInsecureURLB,
-       kInsecureOriginA},
-      {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kInsecureURLA,
-       kInsecureURLB, kInsecureOriginA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA,
+       insecure_origin_a, kInsecureURLB, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, insecure_origin_a,
        kInsecureURLB, nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA,
+       insecure_origin_a, kInsecureURLB, kInsecureOriginA},
+      {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kInsecureURLA,
+       insecure_origin_a, kInsecureURLB, kInsecureOriginA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA,
+       insecure_origin_a, kInsecureURLB, nullptr},
       {network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
-       kInsecureURLB, kInsecureOriginA},
+       insecure_origin_a, kInsecureURLB, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kInsecureURLA, kInsecureURLB, kInsecureOriginA},
+       kInsecureURLA, insecure_origin_a, kInsecureURLB, kInsecureOriginA},
 
       // HTTPS -> HTTPS: Same Origin
-      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, kSecureURLA,
-       kSecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, kSecureURLA,
-       kSecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, secure_origin_a,
+       kSecureURLA, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, secure_origin_a,
+       kSecureURLA, kSecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kSecureURLA,
-       kSecureURLA, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, kSecureURLA,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, kSecureURLA,
-       kSecureOriginA},
+       secure_origin_a, kSecureURLA, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, secure_origin_a,
+       kSecureURLA, nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, secure_origin_a,
+       kSecureURLA, kSecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
-       kSecureURLA, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, kSecureURLA,
-       kSecureURLA},
-      {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA, kSecureURLA,
-       kSecureOriginA},
+       secure_origin_a, kSecureURLA, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA,
+       secure_origin_a, kSecureURLA, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA,
+       secure_origin_a, kSecureURLA, kSecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kSecureURLA, kSecureURLA, kSecureURLA},
+       kSecureURLA, secure_origin_a, kSecureURLA, kSecureURLA},
 
       // HTTPS -> HTTPS: Cross Origin
-      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, kSecureURLB,
-       kSecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, kSecureURLB,
-       kSecureURLA},
-      {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kSecureURLA,
+      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, secure_origin_a,
        kSecureURLB, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, kSecureURLB,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, kSecureURLB,
-       kSecureOriginA},
-      {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
+      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, secure_origin_a,
+       kSecureURLB, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kSecureURLA,
+       secure_origin_a, kSecureURLB, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, secure_origin_a,
+       kSecureURLB, nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, secure_origin_a,
        kSecureURLB, kSecureOriginA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, kSecureURLB,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA, kSecureURLB,
-       kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
+       secure_origin_a, kSecureURLB, kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA,
+       secure_origin_a, kSecureURLB, nullptr},
+      {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA,
+       secure_origin_a, kSecureURLB, kSecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kSecureURLA, kSecureURLB, kSecureOriginA},
+       kSecureURLA, secure_origin_a, kSecureURLB, kSecureOriginA},
 
       // HTTP -> HTTPS
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kSecureURLB,
-       kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA, kSecureURLB,
-       kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
+       insecure_origin_a, kSecureURLB, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA,
+       insecure_origin_a, kSecureURLB, kInsecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kInsecureURLA,
-       kSecureURLB, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, kSecureURLB,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA, kSecureURLB,
-       kInsecureOriginA},
+       insecure_origin_a, kSecureURLB, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, insecure_origin_a,
+       kSecureURLB, nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA,
+       insecure_origin_a, kSecureURLB, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kInsecureURLA,
-       kSecureURLB, kInsecureOriginA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA, kSecureURLB,
-       nullptr},
+       insecure_origin_a, kSecureURLB, kInsecureOriginA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA,
+       insecure_origin_a, kSecureURLB, nullptr},
       {network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
-       kSecureURLB, kInsecureOriginA},
+       insecure_origin_a, kSecureURLB, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kInsecureURLA, kSecureURLB, kInsecureOriginA},
+       kInsecureURLA, insecure_origin_a, kSecureURLB, kInsecureOriginA},
 
       // HTTPS -> HTTP
-      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, kInsecureURLB,
-       kSecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, kInsecureURLB,
-       nullptr},
+      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, secure_origin_a,
+       kInsecureURLB, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, secure_origin_a,
+       kInsecureURLB, nullptr},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kSecureURLA,
+       secure_origin_a, kInsecureURLB, nullptr},
+      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, secure_origin_a,
        kInsecureURLB, nullptr},
-      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, kInsecureURLB,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, kInsecureURLB,
-       kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, secure_origin_a,
+       kInsecureURLB, kSecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
-       kSecureURLB, kSecureOriginA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, kInsecureURLB,
-       nullptr},
+       secure_origin_a, kSecureURLB, kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA,
+       secure_origin_a, kInsecureURLB, nullptr},
       {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA,
-       kInsecureURLB, nullptr},
+       secure_origin_a, kInsecureURLB, nullptr},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kSecureURLA, kInsecureURLB, nullptr},
+       kSecureURLA, secure_origin_a, kInsecureURLB, nullptr},
 
       // blob and filesystem URL handling
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kBlobURL,
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
+       insecure_origin_a, kBlobURL, nullptr},
+      {network::mojom::ReferrerPolicy::kAlways, kBlobURL,
+       SecurityOrigin::CreateFromString(kBlobURL), kInsecureURLA, nullptr},
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
+       insecure_origin_a, kFilesystemURL, nullptr},
+      {network::mojom::ReferrerPolicy::kAlways, kFilesystemURL,
+       SecurityOrigin::CreateFromString(kFilesystemURL), kInsecureURLA,
        nullptr},
-      {network::mojom::ReferrerPolicy::kAlways, kBlobURL, kInsecureURLA,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kFilesystemURL,
-       nullptr},
-      {network::mojom::ReferrerPolicy::kAlways, kFilesystemURL, kInsecureURLA,
-       nullptr},
+
+      // Request's origin is cross-origin with referrer URL.
+      {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
+       cross_origin, kSecureURLA, kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
+       cross_origin, kSecureURLB, kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, cross_origin,
+       kSecureURLA, nullptr},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, cross_origin,
+       kSecureURLB, nullptr},
   };
 
   for (TestCase test : inputs) {
     KURL destination(test.destination);
+    String referrer_string = String::FromUTF8(test.referrer);
+    scoped_refptr<const SecurityOrigin> origin = test.origin;
     Referrer result = SecurityPolicy::GenerateReferrer(
-        test.policy, destination, String::FromUTF8(test.referrer));
+        test.policy, origin, destination, referrer_string);
     if (test.expected) {
       EXPECT_EQ(String::FromUTF8(test.expected), result.referrer)
           << "'" << test.referrer << "' to '" << test.destination
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index eb5c20a..15a5e85 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -2113,20 +2113,20 @@
 external/wpt/visual-viewport/viewport-scroll-event-manual.html [ WontFix ]
 external/wpt/visual-viewport/viewport-url-bar-changes-height-manual.html [ WontFix ]
 external/wpt/wake-lock/wakelock-document-hidden-manual.https.html [ WontFix ]
-external/wpt/web-share/share-cancel-manual.html [ WontFix ]
-external/wpt/web-share/share-extra-argument-manual.html [ WontFix ]
-external/wpt/web-share/share-extra-field-manual.html [ WontFix ]
-external/wpt/web-share/share-non-string-manual.html [ WontFix ]
-external/wpt/web-share/share-null-manual.html [ WontFix ]
-external/wpt/web-share/share-simple-manual.html [ WontFix ]
-external/wpt/web-share/share-unicode-strings-manual.html [ WontFix ]
-external/wpt/web-share/share-unicode-strings-nonutf8-manual.html [ WontFix ]
-external/wpt/web-share/share-url-data-manual.html [ WontFix ]
-external/wpt/web-share/share-url-empty-manual.html [ WontFix ]
-external/wpt/web-share/share-url-encoding-manual.html [ WontFix ]
-external/wpt/web-share/share-url-noscheme-manual.html [ WontFix ]
-external/wpt/web-share/share-url-pathonly-manual.html [ WontFix ]
-external/wpt/web-share/share-url-relative-manual.html [ WontFix ]
+external/wpt/web-share/share-cancel-manual.https.html [ WontFix ]
+external/wpt/web-share/share-extra-argument-manual.https.html [ WontFix ]
+external/wpt/web-share/share-extra-field-manual.https.html [ WontFix ]
+external/wpt/web-share/share-non-string-manual.https.html [ WontFix ]
+external/wpt/web-share/share-null-manual.https.html [ WontFix ]
+external/wpt/web-share/share-simple-manual.https.html [ WontFix ]
+external/wpt/web-share/share-unicode-strings-manual.https.html [ WontFix ]
+external/wpt/web-share/share-unicode-strings-nonutf8-manual.https.html [ WontFix ]
+external/wpt/web-share/share-url-data-manual.https.html [ WontFix ]
+external/wpt/web-share/share-url-empty-manual.https.html [ WontFix ]
+external/wpt/web-share/share-url-encoding-manual.https.html [ WontFix ]
+external/wpt/web-share/share-url-noscheme-manual.https.html [ WontFix ]
+external/wpt/web-share/share-url-pathonly-manual.https.html [ WontFix ]
+external/wpt/web-share/share-url-relative-manual.https.html [ WontFix ]
 external/wpt/webstorage/storage_local-manual.html [ WontFix ]
 external/wpt/webstorage/storage_session-manual.html [ WontFix ]
 external/wpt/xhr/send-authentication-existing-session-manual.htm [ WontFix ]
@@ -2266,8 +2266,8 @@
 external/wpt/pointerevents/pointerevent_touch-action-inherit_child-none_touch-manual.html [ WontFix ]
 external/wpt/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html [ WontFix ]
 external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html [ WontFix ]
-external/wpt/web-share/share-files-manual.html [ WontFix ]
-external/wpt/web-share/share-image-manual.html [ WontFix ]
+external/wpt/web-share/share-files-manual.tentative.https.html [ WontFix ]
+external/wpt/web-share/share-image-manual.https.html [ WontFix ]
 external/wpt/uievents/order-of-events/mouse-events/wheel-basic-manual.html [ WontFix ]
 external/wpt/uievents/order-of-events/mouse-events/wheel-scrolling-manual.html [ WontFix ]
 external/wpt/html/webappapis/user-prompts/print-manual.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 80e03330..b6505d0 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -690,7 +690,7 @@
 crbug.com/591099 external/wpt/css/css-text/shaping/shaping-010.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-text/shaping/shaping-011.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-text/word-break/word-break-break-all-inline-006.html [ Failure ]
-crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-trailing-space-inline.html [ Failure ]
+crbug.com/1002815 external/wpt/css/cssom-view/offsetTopLeft-trailing-space-inline.html [ Failure ]
 crbug.com/591099 fast/backgrounds/quirks-mode-line-box-backgrounds.html [ Failure ]
 crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ]
 crbug.com/835484 fast/css/outline-narrowLine.html [ Failure ]
@@ -2178,6 +2178,11 @@
 # Run these tests with under virtual/scalefactor... only.
 crbug.com/567837 fast/hidpi/static [ Skip ]
 
+crbug.com/1002780 [ Linux ] external/wpt/websockets/stream-tentative/backpressure-receive.any.html [ Failure Pass ]
+crbug.com/1002780 [ Linux ] external/wpt/websockets/stream-tentative/backpressure-receive.any.serviceworker.html [ Failure Pass ]
+crbug.com/1002780 [ Linux ] external/wpt/websockets/stream-tentative/backpressure-receive.any.sharedworker.html [ Failure Pass ]
+crbug.com/1002780 [ Linux ] external/wpt/websockets/stream-tentative/backpressure-receive.any.worker.html [ Failure Pass ]
+
 # For win10, see crbug.com/955109
 crbug.com/538697 [ Win Win10 ] virtual/threaded/printing/webgl-oversized-printing.html [ Failure Crash ]
 crbug.com/538697 [ Win ] printing/webgl-oversized-printing.html [ Failure Crash ]
@@ -3112,7 +3117,7 @@
 # is addressed. Uncomment below line when fixing crbug.com/965829.
 #crbug.com/953847 [ Mac ] virtual/compositor_threaded_scrollbar_scrolling/fast/scrolling/scrollbars/scrollbar-button-gesture-target.html [ Failure ]
 crbug.com/987115 [ Win ] virtual/compositor_threaded_scrollbar_scrolling/fast/scrolling/scrollbars/scrollbar-button-gesture-target.html [ Failure Crash ]
-crbug.com/965829 [ Mac Linux ] virtual/compositor_threaded_scrollbar_scrolling/fast/scrolling/scrollbars/scrollbar-button-gesture-target.html [ Failure ]
+crbug.com/965829 [ Mac ] virtual/compositor_threaded_scrollbar_scrolling/fast/scrolling/scrollbars/scrollbar-button-gesture-target.html [ Failure ]
 
 # Some control characters still not visible
 crbug.com/893490 [ Mac ] external/wpt/css/css-text/white-space/control-chars-001.html [ Failure ]
@@ -6221,3 +6226,6 @@
 # Sheriff 2019-09-10
 crbug.com/1002527 [ Debug ] fast/text/large-text-composed-char.html [ Pass Crash ]
 crbug.com/1002686 [ Mac10.13 ] virtual/threaded/http/tests/devtools/tracing/timeline-style/timeline-recalculate-styles.js [ Failure ]
+
+# Sheriff 2019-09-11
+crbug.com/1002828 [ Linux ] virtual/compositor_threaded_scrollbar_scrolling/fast/scrolling/scrollbars/scrollbar-button-gesture-target.html [ Pass Failure Crash ]
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations
index 6334604..ea618f3 100644
--- a/third_party/blink/web_tests/WebDriverExpectations
+++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -172,3 +172,5 @@
 
 # Sheriff 2019-09-10
 crbug.com/1000734 [ Linux ] external/wpt/webdriver/tests/take_screenshot/iframe.py>>test_source_origin[same_origin] [ Failure Pass ]
+# Sheriff 2019-09-11
+crbug.com/1000734 [ Linux ] external/wpt/webdriver/tests/take_screenshot/screenshot.py>>test_format_and_dimensions [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
index c62d132..9e24d7b9 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -6973,99 +6973,99 @@
      {}
     ]
    ],
-   "web-share/share-cancel-manual.html": [
+   "web-share/share-cancel-manual.https.html": [
     [
-     "web-share/share-cancel-manual.html",
+     "web-share/share-cancel-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-extra-argument-manual.html": [
+   "web-share/share-extra-argument-manual.https.html": [
     [
-     "web-share/share-extra-argument-manual.html",
+     "web-share/share-extra-argument-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-extra-field-manual.html": [
+   "web-share/share-extra-field-manual.https.html": [
     [
-     "web-share/share-extra-field-manual.html",
+     "web-share/share-extra-field-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-files-manual.html": [
+   "web-share/share-files-manual.tentative.https.html": [
     [
-     "web-share/share-files-manual.html",
+     "web-share/share-files-manual.tentative.https.html",
      {}
     ]
    ],
-   "web-share/share-image-manual.html": [
+   "web-share/share-image-manual.https.html": [
     [
-     "web-share/share-image-manual.html",
+     "web-share/share-image-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-non-string-manual.html": [
+   "web-share/share-non-string-manual.https.html": [
     [
-     "web-share/share-non-string-manual.html",
+     "web-share/share-non-string-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-null-manual.html": [
+   "web-share/share-null-manual.https.html": [
     [
-     "web-share/share-null-manual.html",
+     "web-share/share-null-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-simple-manual.html": [
+   "web-share/share-simple-manual.https.html": [
     [
-     "web-share/share-simple-manual.html",
+     "web-share/share-simple-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-unicode-strings-manual.html": [
+   "web-share/share-unicode-strings-manual.https.html": [
     [
-     "web-share/share-unicode-strings-manual.html",
+     "web-share/share-unicode-strings-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-unicode-strings-nonutf8-manual.html": [
+   "web-share/share-unicode-strings-nonutf8-manual.https.html": [
     [
-     "web-share/share-unicode-strings-nonutf8-manual.html",
+     "web-share/share-unicode-strings-nonutf8-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-url-data-manual.html": [
+   "web-share/share-url-data-manual.https.html": [
     [
-     "web-share/share-url-data-manual.html",
+     "web-share/share-url-data-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-url-empty-manual.html": [
+   "web-share/share-url-empty-manual.https.html": [
     [
-     "web-share/share-url-empty-manual.html",
+     "web-share/share-url-empty-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-url-encoding-manual.html": [
+   "web-share/share-url-encoding-manual.https.html": [
     [
-     "web-share/share-url-encoding-manual.html",
+     "web-share/share-url-encoding-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-url-noscheme-manual.html": [
+   "web-share/share-url-noscheme-manual.https.html": [
     [
-     "web-share/share-url-noscheme-manual.html",
+     "web-share/share-url-noscheme-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-url-pathonly-manual.html": [
+   "web-share/share-url-pathonly-manual.https.html": [
     [
-     "web-share/share-url-pathonly-manual.html",
+     "web-share/share-url-pathonly-manual.https.html",
      {}
     ]
    ],
-   "web-share/share-url-relative-manual.html": [
+   "web-share/share-url-relative-manual.https.html": [
     [
-     "web-share/share-url-relative-manual.html",
+     "web-share/share-url-relative-manual.https.html",
      {}
     ]
    ],
@@ -50453,30 +50453,6 @@
      {}
     ]
    ],
-   "css/css-grid/grid-items/grid-items-percentage-margins-003.html": [
-    [
-     "css/css-grid/grid-items/grid-items-percentage-margins-003.html",
-     [
-      [
-       "/css/reference/ref-filled-green-100px-square.xht",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
-   "css/css-grid/grid-items/grid-items-percentage-margins-004.html": [
-    [
-     "css/css-grid/grid-items/grid-items-percentage-margins-004.html",
-     [
-      [
-       "/css/reference/ref-filled-green-100px-square.xht",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
    "css/css-grid/grid-items/grid-items-sizing-alignment-001.html": [
     [
      "css/css-grid/grid-items/grid-items-sizing-alignment-001.html",
@@ -89989,18 +89965,6 @@
      {}
     ]
    ],
-   "css/css-values/minmax-length-percentage-interpolate.html": [
-    [
-     "css/css-values/minmax-length-percentage-interpolate.html",
-     [
-      [
-       "/css/reference/ref-filled-green-100px-square-only.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
    "css/css-values/q-unit-case-insensitivity-001.html": [
     [
      "css/css-values/q-unit-case-insensitivity-001.html",
@@ -162544,12 +162508,6 @@
    "html/semantics/scripting-1/the-script-element/module/nested-missing-export.js": [
     []
    ],
-   "html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub-expected.txt": [
-    []
-   ],
-   "html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub-expected.txt": [
-    []
-   ],
    "html/semantics/scripting-1/the-script-element/module/resources/404-but-js.asis": [
     []
    ],
@@ -162586,6 +162544,12 @@
    "html/semantics/scripting-1/the-script-element/module/resources/import-remote-origin-referrer-checker.sub.js": [
     []
    ],
+   "html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js": [
+    []
+   ],
+   "html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers": [
+    []
+   ],
    "html/semantics/scripting-1/the-script-element/module/resources/import-utf8-with-charset-header.js": [
     []
    ],
@@ -180490,27 +180454,15 @@
    "worklets/animation-worklet-credentials.https-expected.txt": [
     []
    ],
-   "worklets/animation-worklet-referrer.https-expected.txt": [
-    []
-   ],
    "worklets/audio-worklet-credentials.https-expected.txt": [
     []
    ],
-   "worklets/audio-worklet-referrer.https-expected.txt": [
-    []
-   ],
    "worklets/layout-worklet-credentials.https-expected.txt": [
     []
    ],
-   "worklets/layout-worklet-referrer.https-expected.txt": [
-    []
-   ],
    "worklets/paint-worklet-credentials.https-expected.txt": [
     []
    ],
-   "worklets/paint-worklet-referrer.https-expected.txt": [
-    []
-   ],
    "worklets/resources/addmodule-window.html": [
     []
    ],
@@ -301478,21 +301430,21 @@
      {}
     ]
    ],
-   "web-share/canShare-files.https.html": [
+   "web-share/canShare-files.tentative.https.html": [
     [
-     "web-share/canShare-files.https.html",
+     "web-share/canShare-files.tentative.https.html",
      {}
     ]
    ],
-   "web-share/canShare-insecure.http.html": [
+   "web-share/canShare-insecure.tentative.http.html": [
     [
-     "web-share/canShare-insecure.http.html",
+     "web-share/canShare-insecure.tentative.http.html",
      {}
     ]
    ],
-   "web-share/canShare.https.html": [
+   "web-share/canShare.tentative.https.html": [
     [
-     "web-share/canShare.https.html",
+     "web-share/canShare.tentative.https.html",
      {}
     ]
    ],
@@ -372997,14 +372949,6 @@
    "e45530b2fd4a380ba62c3b42ba52157cec098a00",
    "testharness"
   ],
-  "css/css-grid/grid-items/grid-items-percentage-margins-003.html": [
-   "dba467c17a82f02d6c5250b54c832c815994ef76",
-   "reftest"
-  ],
-  "css/css-grid/grid-items/grid-items-percentage-margins-004.html": [
-   "5a3da68572ce70b8a97db7f337379ce0a4a7d652",
-   "reftest"
-  ],
   "css/css-grid/grid-items/grid-items-percentage-margins-vertical-lr-001.html": [
    "aa0ff96985878c5f21d7e7a8175b1351e9841656",
    "testharness"
@@ -404209,10 +404153,6 @@
    "ee086ef269d07bf6b0db5d1306a0f24af0ad8fab",
    "testharness"
   ],
-  "css/css-values/minmax-length-percentage-interpolate.html": [
-   "14af1352d1740d32cd52ab069ab1799f87803f5d",
-   "reftest"
-  ],
   "css/css-values/minmax-number-computed.html": [
    "c72c276625466a193bf8829e3ddbb87d7a565dc0",
    "testharness"
@@ -448974,31 +448914,23 @@
    "testharness"
   ],
   "html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html": [
-   "e50c7b525b495dd8cb1ce3540396a14aecec86af",
+   "e640fe468988b33bd992a07a195b7902c4d65d7a",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub-expected.txt": [
-   "cd990f903e1f91b67aff18d537ca62d3ab58ab9a",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html": [
-   "3623ac2ccb2c5daa2a9f1294c1279083ddaa8ad5",
+   "1ca6b1dfda33e5a5dd7fa2b423979cbee8844a31",
    "testharness"
   ],
   "html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html": [
-   "f512982a451b1d24d47965437162213dff919ec5",
+   "a554fb4b0c465136d636839eb96b463bec4f5c2b",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub-expected.txt": [
-   "6720439ba95b710d893477cdf946710ab7a38abb",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html": [
-   "67b055c217dd384fa66e27111254109957683960",
+   "1d470e668992ad546f721138441a80926dd630cb",
    "testharness"
   ],
   "html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html": [
-   "11f60c010f05971d90b9f0bd30b68bd03ee0bf7e",
+   "443731c1b81375b737eeb9723a0c81d19ceab521",
    "testharness"
   ],
   "html/semantics/scripting-1/the-script-element/module/resources/404-but-js.asis": [
@@ -449049,6 +448981,14 @@
    "45a2520b68c84febc2d2f10c5c968fa682462d19",
    "support"
   ],
+  "html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js": [
+   "5a53bcd4d5ed92dc5ba9f035d96eed14fbca45a8",
+   "support"
+  ],
+  "html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers": [
+   "cb762eff806849df46dc758ef7b98b63f27f54c9",
+   "support"
+  ],
   "html/semantics/scripting-1/the-script-element/module/resources/import-utf8-with-charset-header.js": [
    "c2ccab7c621c09bdd7d871e9326e70c8a86e9ce3",
    "support"
@@ -455098,11 +455038,11 @@
    "testharness"
   ],
   "mathml/presentation-markup/operators/embellished-operator-001.html": [
-   "78c5069b90cab40ec2703c6c01c5d8643b5f836d",
+   "b7d9b4945558440edbba2cb5fd3d7629b7f22087",
    "testharness"
   ],
   "mathml/presentation-markup/operators/embellished-operator-002.html": [
-   "da343dd0bc35a79e0f309c38bbff34a69aa7df34",
+   "b7b7f51d75bbad3140f9affe11262b7c69ceadea",
    "testharness"
   ],
   "mathml/presentation-markup/operators/mo-axis-height-1.html": [
@@ -497033,15 +496973,15 @@
    "5238ce954992f94507668167696b314cfddcf71d",
    "support"
   ],
-  "web-share/canShare-files.https.html": [
+  "web-share/canShare-files.tentative.https.html": [
    "98863a4e2112e870d675a657811a3f464552e299",
    "testharness"
   ],
-  "web-share/canShare-insecure.http.html": [
+  "web-share/canShare-insecure.tentative.http.html": [
    "ce81c7c0c8a4e6d023257fce6cbd5ed802fabc2c",
    "testharness"
   ],
-  "web-share/canShare.https.html": [
+  "web-share/canShare.tentative.https.html": [
    "bb263e542559d8676c2dd94b7521ecf345dc712e",
    "testharness"
   ],
@@ -497053,7 +496993,7 @@
    "15bb17936e4479f7338b7cefbaa87522a2a02df4",
    "support"
   ],
-  "web-share/share-cancel-manual.html": [
+  "web-share/share-cancel-manual.https.html": [
    "b078a74251cff1f566107f14e39a3b926f74f16c",
    "manual"
   ],
@@ -497061,27 +497001,27 @@
    "ee1051812c614abb1e3e0b45f27b6b80d03d6bd2",
    "testharness"
   ],
-  "web-share/share-extra-argument-manual.html": [
+  "web-share/share-extra-argument-manual.https.html": [
    "47ef7fa1158578e3b6bf51ac12fd3f486e52b054",
    "manual"
   ],
-  "web-share/share-extra-field-manual.html": [
+  "web-share/share-extra-field-manual.https.html": [
    "8b479bb02b9c91b82a7e71272fc26735a4ca1ca5",
    "manual"
   ],
-  "web-share/share-files-manual.html": [
+  "web-share/share-files-manual.tentative.https.html": [
    "c3941bb4065b28c7f8fd4f615b8ec595ea5281a7",
    "manual"
   ],
-  "web-share/share-image-manual.html": [
+  "web-share/share-image-manual.https.html": [
    "48ea4c378c194691b78d1b365999408322345a37",
    "manual"
   ],
-  "web-share/share-non-string-manual.html": [
+  "web-share/share-non-string-manual.https.html": [
    "b70f8fc23d2e31e1f0ddc0aa62c7ad28917faabf",
    "manual"
   ],
-  "web-share/share-null-manual.html": [
+  "web-share/share-null-manual.https.html": [
    "4c74225cbe7059be50deaf78722e6838cf086c21",
    "manual"
   ],
@@ -497097,27 +497037,27 @@
    "5a71eaa4abf359008d84d1f219083ec1a91a6458",
    "testharness"
   ],
-  "web-share/share-simple-manual.html": [
+  "web-share/share-simple-manual.https.html": [
    "d88beda83c621fb78888557a97b1ff5a2bc08ed0",
    "manual"
   ],
-  "web-share/share-unicode-strings-manual.html": [
+  "web-share/share-unicode-strings-manual.https.html": [
    "8cdaa87de78d5aef6d157a9045320e4fd4ce5f0e",
    "manual"
   ],
-  "web-share/share-unicode-strings-nonutf8-manual.html": [
+  "web-share/share-unicode-strings-nonutf8-manual.https.html": [
    "deabec3def5ff4c3584a4efacf9031722f656aed",
    "manual"
   ],
-  "web-share/share-url-data-manual.html": [
+  "web-share/share-url-data-manual.https.html": [
    "e634c0c01c44c75eb7b348c3f9c6f6b1840fdb98",
    "manual"
   ],
-  "web-share/share-url-empty-manual.html": [
+  "web-share/share-url-empty-manual.https.html": [
    "4038dab8cf24dfc7705a17649c0162a916a9fe47",
    "manual"
   ],
-  "web-share/share-url-encoding-manual.html": [
+  "web-share/share-url-encoding-manual.https.html": [
    "0f03b5a8b7112a210a8b21cde7094a5f2540408f",
    "manual"
   ],
@@ -497125,15 +497065,15 @@
    "5f2545d5e120f8a8af0c5aeb586ec702b82a5c0c",
    "testharness"
   ],
-  "web-share/share-url-noscheme-manual.html": [
+  "web-share/share-url-noscheme-manual.https.html": [
    "e9d7eefeb74f84a38bc9c166731da952866cf986",
    "manual"
   ],
-  "web-share/share-url-pathonly-manual.html": [
+  "web-share/share-url-pathonly-manual.https.html": [
    "0487bc852168a45ecb9885f1691b4c462e851d8c",
    "manual"
   ],
-  "web-share/share-url-relative-manual.html": [
+  "web-share/share-url-relative-manual.https.html": [
    "bbea3860a5895d55fc160eed3ae474ee0b68f52c",
    "manual"
   ],
@@ -507649,10 +507589,6 @@
    "98b56d36250f2f02a38e6fb066b9abbe7b0cf902",
    "testharness"
   ],
-  "worklets/animation-worklet-referrer.https-expected.txt": [
-   "d605c7563fa39501b27a0d574fc611c9a2084356",
-   "support"
-  ],
   "worklets/animation-worklet-referrer.https.html": [
    "494e06a8472795016e2ee346397d7c227477809c",
    "testharness"
@@ -507677,10 +507613,6 @@
    "cff063a4361bd0244ee7a7a352be849f1b7118a6",
    "testharness"
   ],
-  "worklets/audio-worklet-referrer.https-expected.txt": [
-   "d605c7563fa39501b27a0d574fc611c9a2084356",
-   "support"
-  ],
   "worklets/audio-worklet-referrer.https.html": [
    "f258cd5a452d57002d041211cb44ee6f27f0b3aa",
    "testharness"
@@ -507709,10 +507641,6 @@
    "a2f57c221b7f6f020dda72bb9b2395cfd05d5c03",
    "testharness"
   ],
-  "worklets/layout-worklet-referrer.https-expected.txt": [
-   "d605c7563fa39501b27a0d574fc611c9a2084356",
-   "support"
-  ],
   "worklets/layout-worklet-referrer.https.html": [
    "cb383a935a2a6d154d804595e78275e289076a4c",
    "testharness"
@@ -507737,10 +507665,6 @@
    "68e926c8c18868b84069bf18eb0bae6a37a77ce4",
    "testharness"
   ],
-  "worklets/paint-worklet-referrer.https-expected.txt": [
-   "d605c7563fa39501b27a0d574fc611c9a2084356",
-   "support"
-  ],
   "worklets/paint-worklet-referrer.https.html": [
    "a4b5a6f498c2755d498fd22afc1ab7398fab56ec",
    "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-003.html
deleted file mode 100644
index dba467c..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-003.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Grid Layout Test: Grid items with percentage margins</title>
-<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
-<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
-<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout.">
-<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
-<link rel="stylesheet" href="support/grid.css">
-<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
-<style>
-.container {
-    font: 25px/1 Ahem;
-    width: 100px;
-    height: 100px;
-}
-.child {
-    margin: 50px;
-    color: red;
-}
-.ref {
-    position: absolute;
-    z-index: -1;
-    background: green;
-}
-.grid {
-    background: none;
-}
-#item {
-    margin: 50%;
-    color: green;
-}
-</style>
-<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
-<div class="container ref"><div class="child">X</div></div>
-<div class="container grid"><div class="child" id="item">X</div></div>
-<script>
-    item.style.width = "0px";
-    item.offsetLeft;
-    item.style.width = "auto";
-    item.offsetLeft;
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-004.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-004.html
deleted file mode 100644
index 5a3da68..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-004.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Grid Layout Test: Grid items with percentage margins</title>
-<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
-<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
-<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout.">
-<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
-<link rel="stylesheet" href="support/grid.css">
-<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
-<style>
-.container {
-    width: 100px;
-    height: 100px;
-}
-.child {
-    width: 25px;
-    height: 25px;
-    margin: 50px;
-    background: red;
-}
-.ref {
-    position: absolute;
-    z-index: -1;
-    background: green;
-}
-.grid {
-    background: none;
-}
-#item {
-    margin: 50%;
-    background: green;
-}
-</style>
-<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
-<div class="container ref"><div class="child"></div></div>
-<div class="container grid"><div class="child" id="item"></div></div>
-<script>
-    item.style.width = "0px";
-    item.offsetLeft;
-    item.style.width = "25px";
-    item.offsetLeft;
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percentage-interpolate.html b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percentage-interpolate.html
deleted file mode 100644
index 14af1352..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percentage-interpolate.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype html>
-<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
-<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
-<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
-<title>Tests interpolation between CSS comparison functions</title>
-<style>
-@keyframes anim {
-  from {
-    width:  min(50px, 30%);
-    height: min(75%, 160px);
-  }
-  to {
-    width:  max(75%, 100px);
-    height: max(50px, 20%);
-  }
-}
-
-.test {
-  background-color: green;
-  animation: anim 2000000s linear;
-  animation-delay: -1000000s;
-}
-
-.container {
-  position: absolute;
-  width: 200px;
-  height: 200px;
-}
-</style>
-<p>Test passes if there is a filled green square.</p>
-<div class="container">
-  <div class="test"></div>
-</div>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/geolocation-report-only.https-expected.txt b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/geolocation-report-only.https-expected.txt
index 9322061..c7c46f13 100644
--- a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/geolocation-report-only.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/geolocation-report-only.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Geolocation report only mode promise_test: Unhandled rejection with value: object "[object PositionError]"
+FAIL Geolocation report only mode promise_test: Unhandled rejection with value: object "[object GeolocationPositionError]"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https-expected.txt b/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https-expected.txt
index cacf8e36..a399a8b 100644
--- a/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https-expected.txt
@@ -1,7 +1,7 @@
 This is a testharness.js-based test.
 FAIL getCurrentPosition success callback tests assert_unreached: Error callback called in error Reached unreachable code
 PASS getCurrentPosition error callback tests
-PASS PositionError toString
+PASS GeolocationPositionError toString
 PASS PERMISSION_DENIED value is 1
 PASS POSITION_UNAVAILABLE is 2
 PASS TIMEOUT value is 3
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https.html b/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https.html
index 75426fc..1688c86 100644
--- a/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https.html
+++ b/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https.html
@@ -20,31 +20,29 @@
   var ii, oldval;
 
   /*
-    [NoInterfaceObject]
-    interface Position {
-      readonly attribute Coordinates coords;
+    interface GeolocationPosition {
+      readonly attribute GeolocationCoordinates coords;
       readonly attribute DOMTimeStamp timestamp;
     };
   */
 
   test(function() {
-    assert_equals(position.toString(), "[object Position]",
-        "Position.toString should result in '[object Position]' was: " + position.toString());
-  }, "Position toString");
+    assert_equals(position.toString(), "[object GeolocationPosition]",
+        "position.toString should result in '[object GeolocationPosition]' was: " + position.toString());
+  }, "GeolocationPosition toString");
 
   test(function() {
-    assert_equals(position.coords.toString(), "[object Coordinates]",
-        "position.coords.toString should result in '[object Coordinates]' was: " + position.coords.toString());
-  }, "Position.coordinates toString");
+    assert_equals(position.coords.toString(), "[object GeolocationCoordinates]",
+        "position.coords.toString should result in '[object GeolocationCoordinates]' was: " + position.coords.toString());
+  }, "GeolocationCoordinates toString");
 
   test(function() {
     assert_equals(typeof(position.timestamp), "number",
-        "Position.timestamp should be of type 'number' was: " + typeof(position.timestamp));
-  }, "Position.timestamp is type number");
+        "position.timestamp should be of type 'number' was: " + typeof(position.timestamp));
+  }, "GeolocationPosition.timestamp is type number");
 
   /*
-    [NoInterfaceObject]
-    interface Coordinates {
+    interface GeolocationCoordinates {
       readonly attribute double latitude;
       readonly attribute double longitude;
       readonly attribute double? altitude;
@@ -103,10 +101,10 @@
 function errorCallback(error)
 {
   test(function() {
-    assert_equals(error.toString(), "[object PositionError]",
-        "PositionError.toString should result in '[object PositionError]' was: " +
+    assert_equals(error.toString(), "[object GeolocationPositionError]",
+        "error.toString should result in '[object GeolocationPositionError]' was: " +
         error.toString());
-  }, "PositionError toString");
+  }, "GeolocationPositionError toString");
 
   test(function() {
     assert_equals(error.PERMISSION_DENIED, 1,
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window-expected.txt
deleted file mode 100644
index 5f60ebaf..0000000
--- a/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window-expected.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-This is a testharness.js-based test.
-Found 56 tests; 11 PASS, 45 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS Partial interface Navigator: original interface defined
-FAIL Geolocation interface: existence and properties of interface object assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation interface object length assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation interface object name assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation interface: existence and properties of interface prototype object assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation interface: operation getCurrentPosition(PositionCallback, PositionErrorCallback, PositionOptions) assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation interface: operation watchPosition(PositionCallback, PositionErrorCallback, PositionOptions) assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation interface: operation clearWatch(long) assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-FAIL Geolocation must be primary interface of navigator.geolocation assert_own_property: self does not have own property "Geolocation" expected property "Geolocation" missing
-PASS Stringification of navigator.geolocation
-PASS Geolocation interface: navigator.geolocation must inherit property "getCurrentPosition(PositionCallback, PositionErrorCallback, PositionOptions)" with the proper type
-PASS Geolocation interface: calling getCurrentPosition(PositionCallback, PositionErrorCallback, PositionOptions) on navigator.geolocation with too few arguments must throw TypeError
-PASS Geolocation interface: navigator.geolocation must inherit property "watchPosition(PositionCallback, PositionErrorCallback, PositionOptions)" with the proper type
-PASS Geolocation interface: calling watchPosition(PositionCallback, PositionErrorCallback, PositionOptions) on navigator.geolocation with too few arguments must throw TypeError
-PASS Geolocation interface: navigator.geolocation must inherit property "clearWatch(long)" with the proper type
-PASS Geolocation interface: calling clearWatch(long) on navigator.geolocation with too few arguments must throw TypeError
-FAIL GeolocationPosition interface: existence and properties of interface object assert_own_property: self does not have own property "GeolocationPosition" expected property "GeolocationPosition" missing
-FAIL GeolocationPosition interface object length assert_own_property: self does not have own property "GeolocationPosition" expected property "GeolocationPosition" missing
-FAIL GeolocationPosition interface object name assert_own_property: self does not have own property "GeolocationPosition" expected property "GeolocationPosition" missing
-FAIL GeolocationPosition interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GeolocationPosition" expected property "GeolocationPosition" missing
-FAIL GeolocationPosition interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GeolocationPosition" expected property "GeolocationPosition" missing
-FAIL GeolocationPosition interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GeolocationPosition" expected property "GeolocationPosition" missing
-FAIL GeolocationPosition interface: attribute coords assert_own_property: self does not have own property "GeolocationPosition" expected property "GeolocationPosition" missing
-FAIL GeolocationPosition interface: attribute timestamp assert_own_property: self does not have own property "GeolocationPosition" expected property "GeolocationPosition" missing
-FAIL GeolocationCoordinates interface: existence and properties of interface object assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface object length assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface object name assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: attribute latitude assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: attribute longitude assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: attribute altitude assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: attribute accuracy assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: attribute altitudeAccuracy assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: attribute heading assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationCoordinates interface: attribute speed assert_own_property: self does not have own property "GeolocationCoordinates" expected property "GeolocationCoordinates" missing
-FAIL GeolocationPositionError interface: existence and properties of interface object assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface object length assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface object name assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: constant PERMISSION_DENIED on interface object assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: constant PERMISSION_DENIED on interface prototype object assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: constant POSITION_UNAVAILABLE on interface object assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: constant POSITION_UNAVAILABLE on interface prototype object assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: constant TIMEOUT on interface object assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: constant TIMEOUT on interface prototype object assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: attribute code assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-FAIL GeolocationPositionError interface: attribute message assert_own_property: self does not have own property "GeolocationPositionError" expected property "GeolocationPositionError" missing
-PASS Navigator interface: attribute geolocation
-PASS Navigator interface: navigator must inherit property "geolocation" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html
index e50c7b52..e640fe4 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html
@@ -21,6 +21,8 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
 test(t => {
   assert_equals(
       referrerSame, "",
@@ -49,9 +51,9 @@
 
 test(t => {
   assert_equals(
-      referrerRemoteRemote, "",
-      "Referrer should not be sent for the remote-origin descendant script.");
-}, "Importing a remote-origin descendant script from a remote-origin " +
+      referrerRemoteSame, "",
+      "Referrer should not be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
    "top-level script with the no-referrer policy.");
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub-expected.txt
deleted file mode 100644
index cd990f90..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Importing a same-origin top-level script with the origin-when-cross-origin policy.
-PASS Importing a remote-origin top-level script with the origin-when-cross-origin policy.
-PASS Importing a same-origin descendant script from a same-origin top-level script with the origin-when-cross-origin policy.
-PASS Importing a remote-origin descendant script from a same-origin top-level script with the origin-when-cross-origin policy.
-FAIL Importing a remote-origin descendant script from a remote-origin top-level script with the origin-when-cross-origin policy. assert_equals: Referrer should be sent for the remote-origin descendant script. expected "http://www1.web-platform.test:8001/" but got "http://www1.web-platform.test:8001/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html
index 3623ac2..1ca6b1df 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html
@@ -21,6 +21,8 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
 const origin = (new URL(location.href)).origin + "/";
 const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
 
@@ -37,7 +39,6 @@
       "Referrer should be sent for the remote-origin top-level script.");
 }, "Importing a remote-origin top-level script with the " +
    "origin-when-cross-origin policy.");
-
 test(t => {
   const scriptURL =
       new URL("resources/import-referrer-checker.sub.js", location.href)
@@ -46,7 +47,6 @@
       "Referrer should be sent for the same-origin descendant script.");
 }, "Importing a same-origin descendant script from a same-origin top-level " +
    "script with the origin-when-cross-origin policy.");
-
 test(t => {
   assert_equals(
       referrerSameRemote, origin,
@@ -61,6 +61,16 @@
 }, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the origin-when-cross-origin policy.");
 
+test(t => {
+  const scriptURL = new URL(
+    "html/semantics/scripting-1/the-script-element/module/resources/" +
+    "import-same-origin-referrer-checker-from-remote-origin.sub.js",
+    remoteOrigin);
+  assert_equals(referrerRemoteSame, scriptURL + "?name=remote_same",
+      "Referrer should be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+   "top-level script with the origin-when-cross-origin policy.");
+
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html
index f512982..a554fb4 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html
@@ -21,6 +21,8 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
 const origin = (new URL(location.href)).origin + "/";
 const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
 
@@ -57,6 +59,13 @@
 }, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the origin policy.");
 
+test(t => {
+  assert_equals(
+      referrerRemoteSame, remoteOrigin,
+      "Referrer should be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+   "top-level script with the origin policy.");
+
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub-expected.txt
deleted file mode 100644
index 6720439..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Importing a same-origin top-level script with the same-origin policy.
-PASS Importing a remote-origin top-level script with the same-origin policy.
-PASS Importing a same-origin descendant script from a same-origin top-level script with the same-origin policy.
-PASS Importing a remote-origin descendant script from a same-origin top-level script with the same-origin policy.
-FAIL Importing a remote-origin descendant script from a remote-origin top-level script with the same-origin policy. assert_equals: Referrer should not be sent for the remote-origin descendant script even if it is imported from the script in the same remote-origin. expected "" but got "http://www1.web-platform.test:8001/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html
index 67b055c..1d470e6 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html
@@ -21,6 +21,10 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
+const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
+
 test(t => {
   assert_equals(
       referrerSame, location.href,
@@ -57,6 +61,18 @@
 }, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the same-origin policy.");
 
+test(t => {
+  const scriptURL = new URL(
+    "html/semantics/scripting-1/the-script-element/module/resources/" +
+    "import-same-origin-referrer-checker-from-remote-origin.sub.js",
+    remoteOrigin);
+  assert_equals(
+      referrerRemoteSame, scriptURL + "?name=remote_same",
+      "Referrer should be sent for the same-origin descendant script " +
+      "even if it is imported from the script in the remote-origin.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+   "top-level script with the same-origin policy.");
+
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html
index 11f60c0..443731c 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html
@@ -21,6 +21,8 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
 test(t => {
   assert_equals(
       referrerSame, location.href,
@@ -63,6 +65,17 @@
 }, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the unsafe-url policy.");
 
+test(t => {
+  const scriptURL =
+      "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/" +
+      "scripting-1/the-script-element/module/resources/" +
+      "import-same-origin-referrer-checker-from-remote-origin.sub.js";
+  assert_equals(
+      referrerRemoteSame, scriptURL + "?name=remote_same",
+      "Referrer should be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+   "top-level script with the unsafe-url policy.");
+
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js
new file mode 100644
index 0000000..5a53bcd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js
@@ -0,0 +1,2 @@
+import { referrer as referrerImport } from 'http://{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name={{GET[name]}}';
+export const referrer = referrerImport;
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers
new file mode 100644
index 0000000..cb762ef
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers
@@ -0,0 +1 @@
+Access-Control-Allow-Origin: *
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/embellished-operator-001.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/embellished-operator-001.html
index 78c5069..b7d9b4945 100644
--- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/embellished-operator-001.html
+++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/embellished-operator-001.html
@@ -27,6 +27,15 @@
       color: blue !important;
       background: blue !important;
   }
+  .oof1 {
+      position: absolute;
+  }
+  .oof2 {
+      position: fixed;
+  }
+  .nobox {
+      display: none;
+  }
 </style>
 <script>
   function spaceBeforeElement(id) {
@@ -51,15 +60,27 @@
       ["mrow", "mstyle", "mphantom", "mpadded"].forEach(tag => {
           test(function() {
               assert_true(MathMLFeatureDetection.has_operator_spacing());
-              assert_approx_equals(spaceBeforeElement(`${tag}-op`), 2 * emToPx, epsilon);
-              assert_approx_equals(spaceBeforeCoreOperator(`${tag}-op`), 0, epsilon);
+              assert_approx_equals(spaceBeforeElement(`${tag}-op-1`), 2 * emToPx, epsilon);
+              assert_approx_equals(spaceBeforeCoreOperator(`${tag}-op-1`), 0, epsilon);
           }, `${tag} (embellished operator)`);
 
           test(function() {
               assert_true(MathMLFeatureDetection.has_operator_spacing());
-              assert_approx_equals(spaceBeforeElement(`${tag}-nonop`), 0, epsilon);
-              assert_approx_equals(spaceBeforeCoreOperator(`${tag}-nonop`), 2 * emToPx, epsilon);
+              assert_approx_equals(spaceBeforeElement(`${tag}-op-2`), 2 * emToPx, epsilon);
+              assert_approx_equals(spaceBeforeCoreOperator(`${tag}-op-2`), 0, epsilon);
+          }, `${tag} (embellished operator, from in-flow children)`);
+
+          test(function() {
+              assert_true(MathMLFeatureDetection.has_operator_spacing());
+              assert_approx_equals(spaceBeforeElement(`${tag}-nonop-1`), 0, epsilon);
+              assert_approx_equals(spaceBeforeCoreOperator(`${tag}-nonop-1`), 2 * emToPx, epsilon);
           }, `${tag} (not embellished operator)`);
+
+          test(function() {
+              assert_true(MathMLFeatureDetection.has_operator_spacing());
+              assert_approx_equals(spaceBeforeElement(`${tag}-nonop-2`), 0, epsilon);
+              assert_approx_equals(spaceBeforeCoreOperator(`${tag}-nonop-2`), 2 * emToPx, epsilon);
+          }, `${tag} (not embellished operator, from in-flow children)`);
       });
 
       done();
@@ -68,10 +89,12 @@
 </head>
 <body>
   <div id="log"></div>
+  <!-- mrow is an embellished operator if its in-flow children consist
+       of one embellished operator and zero or more space-like elements. -->
   <p>
     <math>
       <mn>X</mn>
-      <mrow id="mrow-op" class="testedElement">
+      <mrow id="mrow-op-1" class="testedElement">
         <mo lspace="2em" rspace="0em">X</mo>
         <mtext class="space-like">X</mtext>
       </mrow>
@@ -81,19 +104,53 @@
   <p>
     <math>
       <mn>X</mn>
-      <mrow id="mrow-nonop" class="testedElement">
+      <mrow id="mrow-nonop-1" class="testedElement">
         <mo lspace="2em" rspace="0em">X</mo>
         <mn>X</mn> <!-- "mn" is not space-like -->
       </mrow>
       <mn>X</mn>
     </math>
   </p>
-  <!-- mstyle is an embellished operator if its children consist
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mrow id="mrow-op-1" class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mtext class="space-like">X</mtext>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mrow>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mrow id="mrow-nonop-2" class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn> <!-- "mn" is not space-like -->
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mrow>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <!-- mstyle is an embellished operator if its in-flow children consist
        of one embellished operator and zero or more space-like elements. -->
   <p>
     <math>
       <mn>X</mn>
-      <mstyle id="mstyle-op" class="testedElement">
+      <mstyle id="mstyle-op-1" class="testedElement">
         <mo lspace="2em" rspace="0em">X</mo>
       </mstyle>
       <mn>X</mn>
@@ -102,19 +159,51 @@
   <p>
     <math>
       <mn>X</mn>
-      <mstyle id="mstyle-nonop" class="testedElement">
+      <mstyle id="mstyle-nonop-1" class="testedElement">
         <mo lspace="2em" rspace="0em">X</mo>
         <mn>X</mn> <!-- "mn" is not space-like -->
       </mstyle>
       <mn>X</mn>
     </math>
   </p>
-  <!-- mphantom is an embellished operator if its children consist
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mstyle id="mstyle-op-2" class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mstyle>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mstyle id="mstyle-nonop-2" class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn> <!-- "mn" is not space-like -->
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mstyle>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <!-- mphantom is an embellished operator if its in-flow children consist
        of one embellished operator and zero or more space-like elements. -->
   <p>
     <math>
       <mn>X</mn>
-      <mphantom id="mphantom-op" class="testedElement">
+      <mphantom id="mphantom-op-1" class="testedElement">
         <mo lspace="2em" rspace="0em">X</mo>
       </mphantom>
       <mn>X</mn>
@@ -123,19 +212,51 @@
   <p>
     <math>
       <mn>X</mn>
-      <mphantom id="mphantom-nonop" class="testedElement">
+      <mphantom id="mphantom-nonop-1" class="testedElement">
         <mo lspace="2em" rspace="0em">X</mo>
         <mn>X</mn> <!-- "mn" is not space-like -->
       </mphantom>
       <mn>X</mn>
     </math>
   </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mphantom id="mphantom-op-2" class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mphantom>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mphantom id="mphantom-nonop-2" class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn> <!-- "mn" is not space-like -->
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mphantom>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
   <!-- mpadded is an embellished operator if its children consist
        of one embellished operator and zero or more space-like elements. -->
   <p>
     <math>
       <mn>X</mn>
-      <mpadded id="mpadded-op" class="testedElement">
+      <mpadded id="mpadded-op-1" class="testedElement">
         <mo lspace="2em" rspace="0em">X</mo>
       </mpadded>
       <mn>X</mn>
@@ -144,12 +265,44 @@
   <p>
     <math>
       <mn>X</mn>
-      <mpadded id="mpadded-nonop" class="testedElement">
+      <mpadded id="mpadded-nonop-1" class="testedElement">
         <mo lspace="2em" rspace="0em">X</mo>
         <mn>X</mn> <!-- "mn" is not space-like -->
       </mpadded>
       <mn>X</mn>
     </math>
   </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mpadded id="mpadded-op-2" class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mpadded>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mpadded id="mpadded-nonop-2" class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn> <!-- "mn" is not space-like -->
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mpadded>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/embellished-operator-002.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/embellished-operator-002.html
index da343dd..b7b7f51 100644
--- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/embellished-operator-002.html
+++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/embellished-operator-002.html
@@ -30,6 +30,15 @@
       color: blue !important;
       background: blue !important;
   }
+  .oof1 {
+      position: absolute;
+  }
+  .oof2 {
+      position: fixed;
+  }
+  .nobox {
+      display: none;
+  }
 </style>
 <script>
   function spaceBeforeElement(element) {
@@ -55,8 +64,20 @@
            test(function() {
                assert_true(MathMLFeatureDetection.has_operator_spacing());
                var element = document.getElementsByTagName(tag)[1];
+               assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon);
+           }, `${tag} (embellished operator, from in-flow children)`);
+
+           test(function() {
+               assert_true(MathMLFeatureDetection.has_operator_spacing());
+               var element = document.getElementsByTagName(tag)[2];
                assert_approx_equals(spaceBeforeElement(element), 0, epsilon);
            }, `${tag} (not embellished operator)`);
+
+           test(function() {
+               assert_true(MathMLFeatureDetection.has_operator_spacing());
+               var element = document.getElementsByTagName(tag)[3];
+               assert_approx_equals(spaceBeforeElement(element), 0, epsilon);
+           }, `${tag} (not embellished operator, from in-flow children)`);
       });
       done();
   }
@@ -66,7 +87,8 @@
   <div id="log"></div>
   <!-- <msub>, <msup>, <msubsup>, <munder>, <mover>, <munderover>,
        <mmultiscripts>, <mfrac>, <semantics> or <maction> are embellished
-       operators if their first child exists and is an embellished operator -->
+       operators if their first in-flow
+       child exists and is an embellished operator -->
   <p>
     <math>
       <mn>X</mn>
@@ -172,9 +194,192 @@
       <mn>X</mn>
     </math>
   </p>
+
+  <!-- Only in-flow children affect determination of embellished operators. -->
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <msub class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </msub>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <msup class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </msup>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <msubsup class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </msubsup>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <munder class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </munder>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mover class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mover>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <munderover class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </munderover>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mmultiscripts class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mmultiscripts>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mfrac class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mfrac>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <maction class="testedElement" actiontype="statusline">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>STATUS MESSAGE</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </maction>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <semantics class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <annotation>TEXT ANNOTATION</annotation>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </semantics>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+
   <!-- <msub>, <msup>, <msubsup>, <munder>, <mover>, <munderover>,
        <mmultiscripts>, <mfrac>, <semantics> or <maction> are not embellished
-       operators if their first child is not an embellished operator -->
+       operators if their first in-flow child is not an embellished operator -->
   <p>
     <math>
       <mn>X</mn>
@@ -282,5 +487,192 @@
       <mn>X</mn>
     </math>
   </p>
+
+  <!-- Only in-flow children affect determination of embellished operators. -->
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <msub class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </msub>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <msup class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </msup>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <msubsup class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </msubsup>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <munder class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </munder>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mover class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mover>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <munderover class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </munderover>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mmultiscripts class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mmultiscripts>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mfrac class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">X</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </mfrac>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <maction class="testedElement" actiontype="statusline">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mn>X</mn>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mo lspace="2em" rspace="0em">STATUS MESSAGE</mo>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </maction>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+  <p>
+    <math>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <semantics class="testedElement">
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <mrow>
+          <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+          <mn>X</mn>
+          <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+          <mo lspace="2em" rspace="0em">X</mo>
+          <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        </mrow>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+        <annotation>TEXT ANNOTATION</annotation>
+        <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      </semantics>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+      <mn>X</mn>
+      <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+    </math>
+  </p>
+
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resource_ignore_failures.html b/third_party/blink/web_tests/external/wpt/resource-timing/resource_ignore_failures.html
deleted file mode 100644
index fa9e411..0000000
--- a/third_party/blink/web_tests/external/wpt/resource-timing/resource_ignore_failures.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8" />
-<title>Resource Timing ignores failed resources</title>
-<link rel="author" title="Google" href="http://www.google.com/" />
-<link rel="help" href="http://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-initiatortype"/>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="resources/webperftestharness.js"></script>
-<script src="resources/webperftestharnessextension.js"></script>
-<script>
-let iframe;
-function setup_iframe() {
-    const iframe_content = '<img src="resources/non-existing-file.png"></img>';
-    iframe = document.getElementById('frameContext');
-    iframe.contentWindow.document.write(iframe_content);
-}
-function onload_test() {
-    const context = new PerformanceContext(iframe.contentWindow.performance);
-    const entries = context.getEntriesByType('resource');
-    test_true(entries.length == 0, "entries.length == 0");
-}
-window.setup_iframe = setup_iframe;
-</script>
-</head>
-<body>
-<h1>Description</h1>
-<p>This test validates that failed resources aren't present in the Resource Timing buffer.</p>
-<div id="log"></div>
-<iframe id="frameContext" onload="onload_test();" src="resources/inject_resource_test.html"></iframe>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/status-code.py b/third_party/blink/web_tests/external/wpt/resource-timing/resources/status-code.py
new file mode 100644
index 0000000..6ddad159
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/status-code.py
@@ -0,0 +1,4 @@
+def main(request, response):
+    status = request.GET.first('status')
+    response.status = (status, "");
+
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/status-codes-create-entry.html b/third_party/blink/web_tests/external/wpt/resource-timing/status-codes-create-entry.html
new file mode 100644
index 0000000..fb4236e6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/status-codes-create-entry.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<img src="resources/status-code.py?status=200">
+<img src="resources/status-code.py?status=307">
+<img src="resources/status-code.py?status=404">
+<img src="resources/status-code.py?status=502">
+<script>
+async_test(t => {
+  window.addEventListener("load", t.step_func(() => {
+    const images = document.getElementsByTagName("img");
+    for (let img of images) {
+      assert_equals(performance.getEntriesByName(img.src).length, 1, img.src);
+    }
+    t.done();
+  }));
+}, "Make sure all status codes are reported");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resource-timing.sub.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resource-timing.sub.https.html
index f0502ca..2a36608 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resource-timing.sub.https.html
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resource-timing.sub.https.html
@@ -98,14 +98,12 @@
               resource: 'resources/missing.jpg',
               mode: 'same-origin',
               description: 'Network fallback load failure',
-              should_no_performance_entry: true,
           });
           verify({
               performance: performance,
               resource: 'resources/missing.jpg',
               mode: 'cross-origin',
               description: 'Network fallback cross-origin load failure',
-              should_no_performance_entry: true,
           });
           // Tests for respondWith(fetch()).
           verify({
diff --git a/third_party/blink/web_tests/external/wpt/web-share/canShare-files.https.html b/third_party/blink/web_tests/external/wpt/web-share/canShare-files.tentative.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/canShare-files.https.html
rename to third_party/blink/web_tests/external/wpt/web-share/canShare-files.tentative.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/canShare-insecure.http.html b/third_party/blink/web_tests/external/wpt/web-share/canShare-insecure.tentative.http.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/canShare-insecure.http.html
rename to third_party/blink/web_tests/external/wpt/web-share/canShare-insecure.tentative.http.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/canShare.https.html b/third_party/blink/web_tests/external/wpt/web-share/canShare.tentative.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/canShare.https.html
rename to third_party/blink/web_tests/external/wpt/web-share/canShare.tentative.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-cancel-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-cancel-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-cancel-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-cancel-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-extra-argument-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-extra-argument-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-extra-argument-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-extra-argument-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-extra-field-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-extra-field-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-extra-field-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-extra-field-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-files-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-files-manual.tentative.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-files-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-files-manual.tentative.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-image-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-image-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-image-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-image-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-non-string-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-non-string-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-non-string-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-non-string-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-null-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-null-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-null-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-null-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-simple-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-simple-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-simple-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-simple-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-unicode-strings-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-unicode-strings-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-unicode-strings-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-unicode-strings-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-unicode-strings-nonutf8-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-unicode-strings-nonutf8-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-unicode-strings-nonutf8-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-unicode-strings-nonutf8-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-url-data-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-url-data-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-url-data-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-url-data-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-url-empty-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-url-empty-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-url-empty-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-url-empty-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-url-encoding-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-url-encoding-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-url-encoding-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-url-encoding-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-url-noscheme-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-url-noscheme-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-url-noscheme-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-url-noscheme-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-url-pathonly-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-url-pathonly-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-url-pathonly-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-url-pathonly-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-url-relative-manual.html b/third_party/blink/web_tests/external/wpt/web-share/share-url-relative-manual.https.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/share-url-relative-manual.html
rename to third_party/blink/web_tests/external/wpt/web-share/share-url-relative-manual.https.html
diff --git a/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt
deleted file mode 100644
index d605c756..0000000
--- a/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
-PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
-PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
-FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt
deleted file mode 100644
index d605c756..0000000
--- a/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
-PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
-PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
-FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt
deleted file mode 100644
index d605c756..0000000
--- a/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
-PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
-PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
-FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt
deleted file mode 100644
index d605c756..0000000
--- a/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
-PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
-PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
-PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
-PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
-FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/flex-item-grid-container-percentage-rows-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/flex-item-grid-container-percentage-rows-expected.txt
deleted file mode 100644
index 3ce6760..0000000
--- a/third_party/blink/web_tests/fast/css-grid-layout/flex-item-grid-container-percentage-rows-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-CONSOLE WARNING: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-columns-rows-get-set-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/grid-columns-rows-get-set-expected.txt
index ed164d6..f1ff3a3 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-columns-rows-get-set-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-columns-rows-get-set-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 Test that setting and getting grid-template-columns and grid-template-rows works as expected
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-columns-rows-get-set-multiple-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/grid-columns-rows-get-set-multiple-expected.txt
index 88de50bd..f44139c 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-columns-rows-get-set-multiple-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-columns-rows-get-set-multiple-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 Test that setting and getting grid-template-columns and grid-template-rows works as expected
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-indefinite-calculated-height-crash-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/grid-indefinite-calculated-height-crash-expected.txt
index 003c7dd5..aa65cff 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-indefinite-calculated-height-crash-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-indefinite-calculated-height-crash-expected.txt
@@ -1,2 +1 @@
-CONSOLE WARNING: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 This test has PASSED if it didn't CRASH on Debug builds.
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/named-grid-line-get-set-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/named-grid-line-get-set-expected.txt
index ccbe735..4c30202 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/named-grid-line-get-set-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/named-grid-line-get-set-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 Test that setting and getting grid-template-columns and grid-template-rows works as expected
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/percent-intrinsic-track-breadth-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/percent-intrinsic-track-breadth-expected.txt
index 76688553..ba5bfed04 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/percent-intrinsic-track-breadth-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/percent-intrinsic-track-breadth-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: line 48: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 This test checks that percentage track breadths of intrinsic size are treated as auto.
 
 XXXXX
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-expected.txt
index b00933a5..62f078c 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: line 48: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 This test checks that percentages of indefinite sizes are treated as min-content (for the min track sizing function) or max-content (for the max track sizing function).
 
 XXX
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-in-auto-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-in-auto-expected.txt
index b00933a5..62f078c 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-in-auto-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-in-auto-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: line 48: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 This test checks that percentages of indefinite sizes are treated as min-content (for the min track sizing function) or max-content (for the max track sizing function).
 
 XXX
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-in-minmax-crash-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-in-minmax-crash-expected.txt
index 902ea07f..1844b13 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-in-minmax-crash-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/percent-of-indefinite-track-size-in-minmax-crash-expected.txt
@@ -1,2 +1 @@
-CONSOLE WARNING: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 The test works as expected if it does not crash.
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/percent-track-breadths-regarding-container-size-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/percent-track-breadths-regarding-container-size-expected.txt
index ff19d200..29459ebb 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/percent-track-breadths-regarding-container-size-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/percent-track-breadths-regarding-container-size-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: line 48: Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively. This change will happen in M70, around October 2018. See https://www.chromestatus.com/feature/6708326821789696 for more details.
 This test checks percentage track breadths are resolved properly regarding the container size.
 
 XX
diff --git a/third_party/blink/web_tests/geolocation-api/position-string-expected.txt b/third_party/blink/web_tests/geolocation-api/position-string-expected.txt
index c2afea7..420eec1 100644
--- a/third_party/blink/web_tests/geolocation-api/position-string-expected.txt
+++ b/third_party/blink/web_tests/geolocation-api/position-string-expected.txt
@@ -5,8 +5,8 @@
 PASS position.coords.latitude is mockLatitude
 PASS position.coords.longitude is mockLongitude
 PASS position.coords.accuracy is mockAccuracy
-PASS position.toString() is "[object Position]"
-PASS position.coords.toString() is "[object Coordinates]"
+PASS position.toString() is "[object GeolocationPosition]"
+PASS position.coords.toString() is "[object GeolocationCoordinates]"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/blink/web_tests/geolocation-api/position-string.html b/third_party/blink/web_tests/geolocation-api/position-string.html
index 2a6207a..2a7d851 100644
--- a/third_party/blink/web_tests/geolocation-api/position-string.html
+++ b/third_party/blink/web_tests/geolocation-api/position-string.html
@@ -30,8 +30,8 @@
     shouldBe('position.coords.latitude', 'mockLatitude');
     shouldBe('position.coords.longitude', 'mockLongitude');
     shouldBe('position.coords.accuracy', 'mockAccuracy');
-    shouldBe('position.toString()', '"[object Position]"');
-    shouldBe('position.coords.toString()', '"[object Coordinates]"');
+    shouldBe('position.toString()', '"[object GeolocationPosition]"');
+    shouldBe('position.coords.toString()', '"[object GeolocationCoordinates]"');
     finishJSTest();
 }, function(e) {
     testFailed('Error callback invoked unexpectedly');
diff --git a/third_party/blink/web_tests/http/tests/devtools/oopif/oopif-performance-monitor-expected.txt b/third_party/blink/web_tests/http/tests/devtools/oopif/oopif-performance-monitor-expected.txt
index 9b79eae9..8ab1731 100644
--- a/third_party/blink/web_tests/http/tests/devtools/oopif/oopif-performance-monitor-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/oopif/oopif-performance-monitor-expected.txt
@@ -26,7 +26,6 @@
 ResourceFetchers
 Resources
 ScriptDuration
-ScriptPromises
 TaskDuration
 TaskOtherDuration
 ThreadTime
diff --git a/third_party/blink/web_tests/http/tests/geolocation-api/geolocation-default-feature-policy.https.sub.html b/third_party/blink/web_tests/http/tests/geolocation-api/geolocation-default-feature-policy.https.sub.html
index 5d14618..4df1560 100644
--- a/third_party/blink/web_tests/http/tests/geolocation-api/geolocation-default-feature-policy.https.sub.html
+++ b/third_party/blink/web_tests/http/tests/geolocation-api/geolocation-default-feature-policy.https.sub.html
@@ -9,7 +9,7 @@
 run_permission_default_header_policy_tests(
   location.protocol + '//localhost:' + location.port,
   'geolocation',
-  'PositionError',
+  'GeolocationPositionError',
   function() { return new Promise((resolve, reject) => {
     navigator.geolocation.getCurrentPosition(resolve, reject); }); });
 
diff --git a/third_party/blink/web_tests/inspector-protocol/performance/perf-push-metrics-expected.txt b/third_party/blink/web_tests/inspector-protocol/performance/perf-push-metrics-expected.txt
index 40bc7a2..14329c5 100644
--- a/third_party/blink/web_tests/inspector-protocol/performance/perf-push-metrics-expected.txt
+++ b/third_party/blink/web_tests/inspector-protocol/performance/perf-push-metrics-expected.txt
@@ -10,7 +10,6 @@
 	MediaKeys
 	Nodes
 	Resources
-	ScriptPromises
 	ContextLifecycleStateObservers
 	V8PerContextDatas
 	WorkerGlobalScopes
@@ -44,7 +43,6 @@
 	MediaKeys
 	Nodes
 	Resources
-	ScriptPromises
 	ContextLifecycleStateObservers
 	V8PerContextDatas
 	WorkerGlobalScopes
@@ -78,7 +76,6 @@
 	MediaKeys
 	Nodes
 	Resources
-	ScriptPromises
 	ContextLifecycleStateObservers
 	V8PerContextDatas
 	WorkerGlobalScopes
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
index 74c207a0..8f04cab 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1914,6 +1914,35 @@
     method constructor
     method playEffect
     method reset
+interface Geolocation
+    attribute @@toStringTag
+    method clearWatch
+    method constructor
+    method getCurrentPosition
+    method watchPosition
+interface GeolocationCoordinates
+    attribute @@toStringTag
+    getter accuracy
+    getter altitude
+    getter altitudeAccuracy
+    getter heading
+    getter latitude
+    getter longitude
+    getter speed
+    method constructor
+interface GeolocationPosition
+    attribute @@toStringTag
+    getter coords
+    getter timestamp
+    method constructor
+interface GeolocationPositionError
+    attribute @@toStringTag
+    attribute PERMISSION_DENIED
+    attribute POSITION_UNAVAILABLE
+    attribute TIMEOUT
+    getter code
+    getter message
+    method constructor
 interface Gyroscope : Sensor
     attribute @@toStringTag
     getter x
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index aec37ea5..f4e5061 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -2513,6 +2513,35 @@
     getter orientation
     getter position
     method constructor
+interface Geolocation
+    attribute @@toStringTag
+    method clearWatch
+    method constructor
+    method getCurrentPosition
+    method watchPosition
+interface GeolocationCoordinates
+    attribute @@toStringTag
+    getter accuracy
+    getter altitude
+    getter altitudeAccuracy
+    getter heading
+    getter latitude
+    getter longitude
+    getter speed
+    method constructor
+interface GeolocationPosition
+    attribute @@toStringTag
+    getter coords
+    getter timestamp
+    method constructor
+interface GeolocationPositionError
+    attribute @@toStringTag
+    attribute PERMISSION_DENIED
+    attribute POSITION_UNAVAILABLE
+    attribute TIMEOUT
+    getter code
+    getter message
+    method constructor
 interface Gyroscope : Sensor
     attribute @@toStringTag
     getter x
diff --git a/third_party/r8/README.chromium b/third_party/r8/README.chromium
index cf254e5..f198a41 100644
--- a/third_party/r8/README.chromium
+++ b/third_party/r8/README.chromium
@@ -7,8 +7,7 @@
 Security Critical: no
 
 Description:
-D8 is a dexer that converts java byte code to dex code. R8 is a proguard-like
-optimizer that also has the ability to dex. D8 is found within R8's repo.
+R8 is a proguard-like optimizer that also has the ability to dex.
 
 Local Modifications:
 Turning off vertical and horizontal class merging, as described in
diff --git a/third_party/r8/cipd.yaml b/third_party/r8/cipd.yaml
index 39ea97e..7ae0224 100644
--- a/third_party/r8/cipd.yaml
+++ b/third_party/r8/cipd.yaml
@@ -5,13 +5,12 @@
 # Example for updating r8 in the current dir:
 #   Run:
 #     cd <r8 code directory>
-#     tools/gradle.py d8 r8 # Building R8
+#     tools/gradle.py r8 # Building R8
 #     cd -
 #
 #     cipd auth-login
-#     rm lib/r8.jar lib/d8.jar
+#     rm lib/r8.jar
 #     cp <r8 code directory>/build/libs/r8.jar lib/r8.jar
-#     cp <r8 code directory>/build/libs/d8.jar lib/d8.jar
 #     java -jar lib/r8.jar --version
 #     cipd create --pkg-def cipd.yaml # Make note of the instance ID
 #   Manually update:
@@ -20,8 +19,6 @@
 
 package: chromium/third_party/r8
 description: >
-  D8 is a dexer that converts java byte code to dex code (part of the R8 repo).
   R8 is a proguard-like optimizer that also has the option to dex.
 data:
-  - file: lib/d8.jar
   - file: lib/r8.jar
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
index 5d14005b..1247c1a 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
+++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
@@ -37,6 +37,8 @@
         options_.warn_unneeded_finalizer = true;
       } else if (arg == "enable-weak-members-in-unmanaged-classes") {
         options_.enable_weak_members_in_unmanaged_classes = true;
+      } else if (arg == "no-gc-finalized") {
+        options_.no_gc_finalized = true;
       } else {
         llvm::errs() << "Unknown blink-gc-plugin argument: " << arg << "\n";
         return false;
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
index 7069f89..c1556d5 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
+++ b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
@@ -229,10 +229,11 @@
         reporter_.ClassContainsGCRoots(info, visitor.gc_roots());
     }
 
-    if (info->NeedsFinalization())
+    if (!options_.no_gc_finalized && info->NeedsFinalization())
       CheckFinalization(info);
 
-    if (options_.warn_unneeded_finalizer && info->IsGCFinalized())
+    if (!options_.no_gc_finalized && options_.warn_unneeded_finalizer &&
+        info->IsGCFinalized())
       CheckUnneededFinalization(info);
   }
 
@@ -381,11 +382,13 @@
   if (base == info->record()) {
     if (!trace_dispatch)
       reporter_.MissingTraceDispatchMethod(info);
-    if (finalized && !finalize_dispatch)
-      reporter_.MissingFinalizeDispatchMethod(info);
-    if (!finalized && finalize_dispatch) {
-      reporter_.ClassRequiresFinalization(info);
-      reporter_.NoteUserDeclaredFinalizer(finalize_dispatch);
+    if (!options_.no_gc_finalized) {
+      if (finalized && !finalize_dispatch)
+        reporter_.MissingFinalizeDispatchMethod(info);
+      if (!finalized && finalize_dispatch) {
+        reporter_.ClassRequiresFinalization(info);
+        reporter_.NoteUserDeclaredFinalizer(finalize_dispatch);
+      }
     }
   }
 
@@ -410,7 +413,8 @@
       reporter_.MissingTraceDispatch(defn, info);
   }
 
-  if (finalized && finalize_dispatch && finalize_dispatch->isDefined(defn)) {
+  if ((finalized || options_.no_gc_finalized) && finalize_dispatch &&
+      finalize_dispatch->isDefined(defn)) {
     CheckDispatchVisitor visitor(info);
     visitor.TraverseStmt(defn->getBody());
     if (!visitor.dispatched_to_receiver())
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h b/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h
index 4af8950..18ebb89 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h
+++ b/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h
@@ -30,6 +30,10 @@
   // TODO(sof): remove this option once safely rolled out.
   bool enable_weak_members_in_unmanaged_classes = false;
 
+  // If |true| don't perform checks on whether a class needs to be derived from
+  // GarbageCollectedFinalized.
+  bool no_gc_finalized = false;
+
   std::set<std::string> ignored_classes;
   std::set<std::string> checked_namespaces;
   std::vector<std::string> ignored_directories;
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 85130add9..5e617a20 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -18040,6 +18040,7 @@
   <int value="600" label="DomainsToCheckForMalwareOfUploadedContent"/>
   <int value="601" label="HSTSPolicyBypassList"/>
   <int value="602" label="ReportDeviceOsUpdateStatus"/>
+  <int value="603" label="DeviceLoginScreenWebUsbAllowDevicesForUrls"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations">
@@ -62583,6 +62584,8 @@
   <int value="10" label="NotValidManifestForWebApp"/>
   <int value="11" label="IntentToPlayStore"/>
   <int value="12" label="WebAppDisabled"/>
+  <int value="13" label="InstallURLRedirected"/>
+  <int value="14" label="InstallURLLoadFailed"/>
 </enum>
 
 <enum name="WebAppInstallSource">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index f704bf7b..379f6e3 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -170754,6 +170754,7 @@
 
 <histogram_suffixes name="PageLoadMetricsClientsServiceWorkerSpecialApps"
     separator=".">
+  <suffix name="docs" label="Custom histogram for the Google Docs page"/>
   <suffix name="inbox" label="Custom histogram for Inbox"/>
   <suffix name="search"
       label="Custom histogram for the Google Search results page"/>
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py
index fa2a7e5..0fb87dd 100755
--- a/tools/perf/process_perf_results.py
+++ b/tools/perf/process_perf_results.py
@@ -57,6 +57,7 @@
   'cc_perftests',
   'gpu_perftests',
   'media_perftests',
+  'views_perftests',
   'xr.vr.common_perftests',
 ]
 
diff --git a/tools/traffic_annotation/sample_traffic_annotation.cc b/tools/traffic_annotation/sample_traffic_annotation.cc
index 361059e..21001fa 100644
--- a/tools/traffic_annotation/sample_traffic_annotation.cc
+++ b/tools/traffic_annotation/sample_traffic_annotation.cc
@@ -10,7 +10,7 @@
 // and
 // out/Debug/gen/components/policy/proto/chrome_settings.proto
 // For more information on policies, please refer to:
-// http://dev.chromium.org/administrators/policy-list-3
+// https://cloud.google.com/docs/chrome-enterprise/policies
 
 // A template for one level traffic annotation.
 void network_traffic_annotation_template() {
@@ -241,4 +241,4 @@
                                   partial_traffic_annotation));
 
   ...
-}
\ No newline at end of file
+}
diff --git a/ui/accessibility/platform/ax_platform_atk_hyperlink.cc b/ui/accessibility/platform/ax_platform_atk_hyperlink.cc
index c3d8f32..e59b7c3 100644
--- a/ui/accessibility/platform/ax_platform_atk_hyperlink.cc
+++ b/ui/accessibility/platform/ax_platform_atk_hyperlink.cc
@@ -12,8 +12,6 @@
 
 struct _AXPlatformAtkHyperlinkPrivate {
   AXPlatformNodeAuraLinux* platform_node = nullptr;
-  base::Optional<int> end_index;
-  base::Optional<int> start_index;
 };
 
 static gpointer kAXPlatformAtkHyperlinkParentClass = nullptr;
@@ -84,13 +82,17 @@
 static int AXPlatformAtkHyperlinkGetStartIndex(AtkHyperlink* atk_hyperlink) {
   g_return_val_if_fail(IS_AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink), 0);
   AXPlatformAtkHyperlink* link = AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink);
-  return link->priv->start_index ? *link->priv->start_index : 0;
+  base::Optional<std::pair<int, int>> indices =
+      link->priv->platform_node->GetEmbeddedObjectIndices();
+  return indices.has_value() ? indices->first : 0;
 }
 
 static int AXPlatformAtkHyperlinkGetEndIndex(AtkHyperlink* atk_hyperlink) {
   g_return_val_if_fail(IS_AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink), 0);
   AXPlatformAtkHyperlink* link = AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink);
-  return link->priv->end_index ? *link->priv->end_index : 0;
+  base::Optional<std::pair<int, int>> indices =
+      link->priv->platform_node->GetEmbeddedObjectIndices();
+  return indices.has_value() ? indices->second : 0;
 }
 
 static void AXPlatformAtkHyperlinkClassInit(AtkHyperlinkClass* klass) {
@@ -231,14 +233,6 @@
   atk_hyperlink->priv->platform_node = platform_node;
 }
 
-void ax_platform_atk_hyperlink_set_indices(
-    AXPlatformAtkHyperlink* atk_hyperlink,
-    int start_index,
-    int end_index) {
-  atk_hyperlink->priv->start_index = start_index;
-  atk_hyperlink->priv->end_index = end_index;
-}
-
 static void AXPlatformAtkHyperlinkInit(AXPlatformAtkHyperlink* self, gpointer) {
   AXPlatformAtkHyperlinkPrivate* priv =
       G_TYPE_INSTANCE_GET_PRIVATE(self, ax_platform_atk_hyperlink_get_type(),
diff --git a/ui/accessibility/platform/ax_platform_atk_hyperlink.h b/ui/accessibility/platform/ax_platform_atk_hyperlink.h
index 733d418..30e9112 100644
--- a/ui/accessibility/platform/ax_platform_atk_hyperlink.h
+++ b/ui/accessibility/platform/ax_platform_atk_hyperlink.h
@@ -46,10 +46,6 @@
 GType ax_platform_atk_hyperlink_get_type(void) G_GNUC_CONST;
 void ax_platform_atk_hyperlink_set_object(AXPlatformAtkHyperlink* hyperlink,
                                           AXPlatformNodeAuraLinux* obj);
-void ax_platform_atk_hyperlink_set_indices(
-    AXPlatformAtkHyperlink* atk_hyperlink,
-    int start_index,
-    int end_index);
 
 G_END_DECLS
 
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 2dc0a86..e217d89 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -3448,6 +3448,14 @@
                         UTF16ToUnicodeOffsetInText(offset->first + 1));
 }
 
+base::Optional<std::pair<int, int>>
+AXPlatformNodeAuraLinux::GetEmbeddedObjectIndices() {
+  auto* parent = AtkObjectToAXPlatformNodeAuraLinux(GetParent());
+  if (!parent)
+    return base::nullopt;
+  return parent->GetEmbeddedObjectIndicesForId(GetUniqueId());
+}
+
 void AXPlatformNodeAuraLinux::UpdateHypertext() {
   EnsureAtkObjectIsValid();
   AXHypertext old_hypertext = hypertext_;
@@ -3819,20 +3827,6 @@
       ATK_HYPERLINK(g_object_new(AX_PLATFORM_ATK_HYPERLINK_TYPE, 0));
   ax_platform_atk_hyperlink_set_object(
       AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink_), this);
-
-  auto* parent = AtkObjectToAXPlatformNodeAuraLinux(GetParent());
-  if (!parent)
-    return atk_hyperlink_;
-
-  base::Optional<std::pair<int, int>> indices =
-      parent->GetEmbeddedObjectIndicesForId(GetUniqueId());
-  if (!indices.has_value())
-    return atk_hyperlink_;
-
-  ax_platform_atk_hyperlink_set_indices(
-      AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink_), indices->first,
-      indices->second);
-
   return atk_hyperlink_;
 }
 
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h
index 2d64e2a..8b723ec0 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -221,6 +221,11 @@
   // return it, otherwise return base::nullopt;
   base::Optional<FindInPageResultInfo> GetSelectionOffsetsFromFindInPage();
 
+  // Get the embedded object ("hyperlink") indices for this object in the
+  // parent. If this object doesn't have a parent or isn't embedded, return
+  // nullopt.
+  base::Optional<std::pair<int, int>> GetEmbeddedObjectIndices();
+
   std::string accessible_name_;
 
  protected:
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
index 421ab1e..9de67ce 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -323,41 +323,6 @@
   }
 };
 
-/**
- * Custom splitter that resizes column with retaining the sum of all the column
- * width.
- */
-const FileTableSplitter = cr.ui.define('div');
-
-/**
- * Inherits from cr.ui.TableSplitter.
- */
-FileTableSplitter.prototype.__proto__ = cr.ui.TableSplitter.prototype;
-
-/**
- * Handles the drag start event.
- */
-FileTableSplitter.prototype.handleSplitterDragStart = function() {
-  cr.ui.TableSplitter.prototype.handleSplitterDragStart.call(this);
-  this.table_.columnModel.handleSplitterDragStart();
-};
-
-/**
- * Handles the drag move event.
- * @param {number} deltaX Horizontal mouse move offset.
- */
-FileTableSplitter.prototype.handleSplitterDragMove = function(deltaX) {
-  this.table_.columnModel.setWidthAndKeepTotal(
-      this.columnIndex, this.columnWidth_ + deltaX, true);
-};
-
-/**
- * Handles the drag end event.
- */
-FileTableSplitter.prototype.handleSplitterDragEnd = function() {
-  cr.ui.TableSplitter.prototype.handleSplitterDragEnd.call(this);
-  this.table_.columnModel.handleSplitterDragEnd();
-};
 
 /**
  * File list Table View.
@@ -517,20 +482,6 @@
     self.relayoutRateLimiter_ =
         new AsyncUtil.RateLimiter(self.relayoutImmediately_.bind(self));
 
-    // Override header#redraw to use FileTableSplitter.
-    /** @this {cr.ui.table.TableHeader} */
-    selfAsTable.header.redraw = function() {
-      this.__proto__.redraw.call(this);
-      // Extend table splitters
-      const splitters = this.querySelectorAll('.table-header-splitter');
-      for (let i = 0; i < splitters.length; i++) {
-        if (splitters[i] instanceof FileTableSplitter) {
-          continue;
-        }
-        FileTableSplitter.decorate(splitters[i]);
-      }
-    };
-
     // Save the last selection. This is used by shouldStartDragSelection.
     self.list.addEventListener('mousedown', function(e) {
       this.lastSelection_ = this.selectionModel.selectedIndexes;
diff --git a/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js b/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js
index 39f4d6f4..a3716de 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js
@@ -453,11 +453,11 @@
                 this.completedHost_.removePanelItem(donePanelItem);
               }
             };
-            // Delete after 7 seconds, doesn't matter if it's manually deleted
+            // Delete after 4 seconds, doesn't matter if it's manually deleted
             // before the timer fires, as removePanelItem handles that case.
             setTimeout(() => {
               this.completedHost_.removePanelItem(donePanelItem);
-            }, 7000);
+            }, 4000);
           }
           // Drop through to remove the progress panel.
         case 'canceled':
diff --git a/ui/file_manager/file_manager/foreground/js/ui/table/table_header.js b/ui/file_manager/file_manager/foreground/js/ui/table/table_header.js
index 0949cfd..e12c9ec9 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/table/table_header.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/table/table_header.js
@@ -7,8 +7,6 @@
  */
 
 cr.define('cr.ui.table', function() {
-  /** @const */ const TableSplitter = cr.ui.TableSplitter;
-
   /**
    * Creates a new table header.
    * @param {Object=} opt_propertyBag Optional properties.
@@ -208,7 +206,7 @@
       let minDistance = TableHeader.TOUCH_DRAG_AREA_WIDTH;
       let candidate;
 
-      const splitters = /** @type {NodeList<cr.ui.TableSplitter>} */ (
+      const splitters = /** @type {NodeList<TableSplitter>} */ (
           this.querySelectorAll('.table-header-splitter'));
       for (let i = 0; i < splitters.length; i++) {
         const r = splitters[i].getBoundingClientRect();
diff --git a/ui/file_manager/file_manager/foreground/js/ui/table/table_splitter.js b/ui/file_manager/file_manager/foreground/js/ui/table/table_splitter.js
index 41050b6..a998f9c 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/table/table_splitter.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/table/table_splitter.js
@@ -10,76 +10,86 @@
  * It is column model responsibility to resize other columns accordingly.
  */
 
-cr.define('cr.ui', function() {
-  /** @const */ const Splitter = cr.ui.Splitter;
-
+/**
+ * Creates a new table splitter element.
+ */
+class TableSplitter extends cr.ui.Splitter {
   /**
-   * Creates a new table splitter element.
    * @param {Object=} opt_propertyBag Optional properties.
-   * @constructor
-   * @extends {cr.ui.Splitter}
    */
-  const TableSplitter = cr.ui.define('div');
+  constructor(opt_propertyBag) {
+    super();
+    // cr.ui magic overwrites __proto__, so here we restore it back.
+    this.__proto__ = TableSplitter.prototype;
 
-  TableSplitter.prototype = {
-    __proto__: Splitter.prototype,
+    /** @private {cr.ui.Table} */
+    this.table_;
+    this.table = (opt_propertyBag && opt_propertyBag.table) || null;
 
-    table_: null,
+    /** @private {number} */
+    this.columnIndex_ = -1;
 
-    columnIndex_: null,
+    /** @private {number} */
+    this.columnWidth_ = 0;
 
-    /**
-     * Initializes the element.
-     */
-    decorate: function() {
-      Splitter.prototype.decorate.call(this);
+    /** @private {number} */
+    this.nextColumnWidth_ = 0;
 
-      this.classList.add('table-header-splitter');
-    },
-
-    /**
-     * Handles start of the splitter dragging.
-     * Saves starting width of the column and changes the cursor.
-     * @override
-     */
-    handleSplitterDragStart: function() {
-      const cm = this.table_.columnModel;
-      this.ownerDocument.documentElement.classList.add('col-resize');
-
-      this.columnWidth_ = cm.getWidth(this.columnIndex);
-      this.nextColumnWidth_ = cm.getWidth(this.columnIndex + 1);
-    },
-
-    /**
-     * Handles spliter moves. Sets new width of the column.
-     * @override
-     */
-    handleSplitterDragMove: function(deltaX) {
-      this.table_.columnModel.setWidth(
-          this.columnIndex, this.columnWidth_ + deltaX);
-    },
-
-    /**
-     * Handles end of the splitter dragging. Restores cursor.
-     * @override
-     */
-    handleSplitterDragEnd: function() {
-      this.ownerDocument.documentElement.classList.remove('col-resize');
-      cr.dispatchSimpleEvent(this, 'column-resize-end', true);
-    },
-  };
+    this.decorate();
+  }
 
   /**
-   * The column index.
-   * @type {number}
+   * Initializes the element.
    */
-  cr.defineProperty(TableSplitter, 'columnIndex');
+  decorate() {
+    super.decorate();
+
+    this.classList.add('table-header-splitter');
+  }
 
   /**
-   * The table associated with the splitter.
-   * @type {Element}
+   * Handles start of the splitter dragging.
+   * Saves starting width of the column and changes the cursor.
+   * @override
    */
-  cr.defineProperty(TableSplitter, 'table');
+  handleSplitterDragStart() {
+    const cm = this.table_.columnModel;
+    this.ownerDocument.documentElement.classList.add('col-resize');
 
-  return {TableSplitter: TableSplitter};
-});
+    this.columnWidth_ = cm.getWidth(this.columnIndex);
+    this.nextColumnWidth_ = cm.getWidth(this.columnIndex + 1);
+
+    this.table_.columnModel.handleSplitterDragStart();
+  }
+
+  /**
+   * Handles spliter moves. Sets new width of the column.
+   * @override
+   */
+  handleSplitterDragMove(deltaX) {
+    this.table_.columnModel.setWidthAndKeepTotal(
+        this.columnIndex, this.columnWidth_ + deltaX, true);
+  }
+
+  /**
+   * Handles end of the splitter dragging. Restores cursor.
+   * @override
+   */
+  handleSplitterDragEnd() {
+    this.ownerDocument.documentElement.classList.remove('col-resize');
+    cr.dispatchSimpleEvent(this, 'column-resize-end', true);
+    this.table_.columnModel.handleSplitterDragEnd();
+  }
+}
+
+/**
+ * The column index.
+ * @type {number}
+ */
+cr.defineProperty(TableSplitter, 'columnIndex');
+
+/**
+ * The table associated with the splitter.
+ * @type {Element}
+ */
+cr.defineProperty(TableSplitter, 'table');
diff --git a/ui/views/controls/button/button.cc b/ui/views/controls/button/button.cc
index 7f28f7c..278286d8c 100644
--- a/ui/views/controls/button/button.cc
+++ b/ui/views/controls/button/button.cc
@@ -239,8 +239,14 @@
 }
 
 void Button::SetHotTracked(bool is_hot_tracked) {
-  if (state_ != STATE_DISABLED)
+  if (state_ != STATE_DISABLED) {
     SetState(is_hot_tracked ? STATE_HOVERED : STATE_NORMAL);
+    if (show_ink_drop_when_hot_tracked_) {
+      AnimateInkDrop(is_hot_tracked ? views::InkDropState::ACTIVATED
+                                    : views::InkDropState::HIDDEN,
+                     nullptr);
+    }
+  }
 
   if (is_hot_tracked)
     NotifyAccessibilityEvent(ax::mojom::Event::kHover, true);
diff --git a/ui/views/controls/button/button.h b/ui/views/controls/button/button.h
index 5e10ba9..c931e34 100644
--- a/ui/views/controls/button/button.h
+++ b/ui/views/controls/button/button.h
@@ -149,12 +149,19 @@
     animate_on_state_change_ = value;
   }
 
+  bool hide_ink_drop_when_showing_context_menu() const {
+    return hide_ink_drop_when_showing_context_menu_;
+  }
   void set_hide_ink_drop_when_showing_context_menu(
       bool hide_ink_drop_when_showing_context_menu) {
     hide_ink_drop_when_showing_context_menu_ =
         hide_ink_drop_when_showing_context_menu;
   }
 
+  void set_show_ink_drop_when_hot_tracked(bool show_ink_drop_when_hot_tracked) {
+    show_ink_drop_when_hot_tracked_ = show_ink_drop_when_hot_tracked;
+  }
+
   void set_ink_drop_base_color(SkColor color) { ink_drop_base_color_ = color; }
   void set_has_ink_drop_action_on_click(bool has_ink_drop_action_on_click) {
     has_ink_drop_action_on_click_ = has_ink_drop_action_on_click;
@@ -346,6 +353,10 @@
   // the context menu.
   bool hide_ink_drop_when_showing_context_menu_ = true;
 
+  // When true, the ink drop ripple will be shown when setting state to hot
+  // tracked with SetHotTracked().
+  bool show_ink_drop_when_hot_tracked_ = false;
+
   // The color of the ripple and hover.
   SkColor ink_drop_base_color_;
 
diff --git a/ui/views/controls/button/menu_button_controller.cc b/ui/views/controls/button/menu_button_controller.cc
index cfebc7f..6e1b693 100644
--- a/ui/views/controls/button/menu_button_controller.cc
+++ b/ui/views/controls/button/menu_button_controller.cc
@@ -102,7 +102,8 @@
       button()->HitTestPoint(event.location()) && !delegate()->InDrag()) {
     Activate(&event);
   } else {
-    button()->AnimateInkDrop(InkDropState::HIDDEN, &event);
+    if (button()->hide_ink_drop_when_showing_context_menu())
+      button()->AnimateInkDrop(InkDropState::HIDDEN, &event);
     ButtonController::OnMouseReleased(event);
   }
 }
diff --git a/ui/views/controls/label_perftest.cc b/ui/views/controls/label_perftest.cc
index e8b5c59..18ae63c4 100644
--- a/ui/views/controls/label_perftest.cc
+++ b/ui/views/controls/label_perftest.cc
@@ -6,7 +6,7 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "base/timer/lap_timer.h"
-#include "testing/perf/perf_test.h"
+#include "testing/perf/perf_result_reporter.h"
 #include "ui/views/test/views_test_base.h"
 
 namespace views {
@@ -34,8 +34,9 @@
     label.GetPreferredSize();
     timer.NextLap();
   }
-  perf_test::PrintResult("LabelPerfTest", std::string(), "GetPreferredSize",
-                         timer.LapsPerSecond(), "runs/s", true);
+  perf_test::PerfResultReporter reporter("LabelPerfTest", "GetPreferredSize");
+  reporter.RegisterImportantMetric("", "runs/s");
+  reporter.AddResult("", timer.LapsPerSecond());
 }
 
 }  // namespace views