diff --git a/AUTHORS b/AUTHORS
index b88e4c4..e4b02b2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -350,6 +350,7 @@
 Jaekyeom Kim <btapiz@gmail.com>
 Jaemin Seo <jaemin86.seo@samsung.com>
 Jaeseok Yoon <yjaeseok@gmail.com>
+Jaeyong Bae <jdragon.bae@gmail.com>
 Jaime Soriano Pastor <jsorianopastor@gmail.com>
 Jake Helfert <jake@helfert.us>
 Jake Hendy <me@jakehendy.com>
diff --git a/DEPS b/DEPS
index 086d1cb..566aa60 100644
--- a/DEPS
+++ b/DEPS
@@ -105,7 +105,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': '2a53275c38fbf73b4dbbe04f4289ab4f75088641',
+  'skia_revision': '60e5b43e85ec064b4b9f63d658c5ca690c6b9163',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -117,7 +117,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': 'd6781dce3d251dfdbaa8d2e3f54be2740c4202b1',
+  'angle_revision': '8ca60805916f3ca953f357dde91bfe6336b39159',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -165,7 +165,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': 'a9a4168ab6e9514493c87e3d301bfa27c60477f9',
+  'catapult_revision': '1e44d066259f5d35087c43fa910e680dcb4c229e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -774,17 +774,6 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/javax_inject': {
-      'packages': [
-          {
-              'package': 'chromium/third_party/javax_inject',
-              'version': 'version:1-cr0',
-          },
-      ],
-      'condition': 'checkout_android',
-      'dep_type': 'cipd',
-  },
-
   'src/third_party/jsoncpp/source':
     Var('chromium_git') + '/external/github.com/open-source-parsers/jsoncpp.git' + '@' + 'f572e8e42e22cfcf5ab0aea26574f408943edfa4', # from svn 248
 
@@ -1644,6 +1633,171 @@
       'dep_type': 'cipd',
   },
 
+  'src/third_party/android_deps/libs/com_google_dagger_dagger': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_android': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_android',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_android_processor': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_android_processor',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_android_support': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_android_support',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_compiler': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_compiler',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_producers': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_producers',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_spi': {
+        'packages': [
+            {
+                'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_spi',
+                'version': 'version:2.17-cr0',
+            },
+        ],
+        'condition': 'checkout_android',
+        'dep_type': 'cipd',
+    },
+
+  'src/third_party/android_deps/libs/com_google_errorprone_javac_shaded': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_errorprone_javac_shaded',
+              'version': 'version:9-dev-r4023-3-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format',
+              'version': 'version:1.5-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_guava_guava': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_guava_guava',
+              'version': 'version:25.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_squareup_javapoet': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_squareup_javapoet',
+              'version': 'version:1.11.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/javax_annotation_jsr250_api': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/javax_annotation_jsr250_api',
+              'version': 'version:1.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/javax_inject_javax_inject': {
+        'packages': [
+            {
+                'package': 'chromium/third_party/android_deps/libs/javax_inject_javax_inject',
+                'version': 'version:1-cr0',
+            },
+        ],
+        'condition': 'checkout_android',
+        'dep_type': 'cipd',
+    },
+
   # === ANDROID_DEPS Generated Code End ===
 }
 
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index 3de7d1b7..792f6094 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -744,11 +744,9 @@
   return metric_recording_settings_;
 }
 
-MSVC_DISABLE_OPTIMIZE()
-bool SequenceManagerImpl::Validate() {
+NOINLINE bool SequenceManagerImpl::Validate() {
   return memory_corruption_sentinel_ == kMemoryCorruptionSentinelValue;
 }
-MSVC_ENABLE_OPTIMIZE()
 
 void SequenceManagerImpl::EnableCrashKeys(
     const char* file_name_crash_key_name,
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn
index 16e2c6e5..250fc137 100644
--- a/base/test/BUILD.gn
+++ b/base/test/BUILD.gn
@@ -100,6 +100,8 @@
     "scoped_mock_clock_override.h",
     "scoped_mock_time_message_loop_task_runner.cc",
     "scoped_mock_time_message_loop_task_runner.h",
+    "scoped_os_info_override_win.cc",
+    "scoped_os_info_override_win.h",
     "scoped_path_override.cc",
     "scoped_path_override.h",
     "scoped_task_environment.cc",
diff --git a/base/test/scoped_os_info_override_win.cc b/base/test/scoped_os_info_override_win.cc
new file mode 100644
index 0000000..b1c4d2f
--- /dev/null
+++ b/base/test/scoped_os_info_override_win.cc
@@ -0,0 +1,62 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_os_info_override_win.h"
+
+#include <windows.h>
+
+#include "base/win/windows_version.h"
+
+namespace base {
+namespace test {
+
+ScopedOSInfoOverride::ScopedOSInfoOverride(Type type)
+    : original_info_(base::win::OSInfo::GetInstance()),
+      overriding_info_(CreateInfoOfType(type)) {
+  *base::win::OSInfo::GetInstanceStorage() = overriding_info_.get();
+}
+
+ScopedOSInfoOverride::~ScopedOSInfoOverride() {
+  *base::win::OSInfo::GetInstanceStorage() = original_info_;
+}
+
+// static
+ScopedOSInfoOverride::UniqueOsInfo ScopedOSInfoOverride::CreateInfoOfType(
+    Type type) {
+  _OSVERSIONINFOEXW version_info = {sizeof(version_info)};
+  _SYSTEM_INFO system_info = {};
+  int os_type = 0;
+
+  switch (type) {
+    case Type::kWin10Pro:
+    case Type::kWin10Home:
+      version_info.dwMajorVersion = 10;
+      version_info.dwMinorVersion = 0;
+      version_info.dwBuildNumber = 15063;
+      version_info.wServicePackMajor = 0;
+      version_info.wServicePackMinor = 0;
+      version_info.szCSDVersion[0] = 0;
+      version_info.wProductType = VER_NT_WORKSTATION;
+      version_info.wSuiteMask = VER_SUITE_PERSONAL;
+
+      system_info.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
+      system_info.dwNumberOfProcessors = 1;
+      system_info.dwAllocationGranularity = 8;
+
+      os_type =
+          type == Type::kWin10Home ? PRODUCT_HOME_BASIC : PRODUCT_PROFESSIONAL;
+      break;
+  }
+
+  return UniqueOsInfo(new base::win::OSInfo(version_info, system_info, os_type),
+                      &ScopedOSInfoOverride::deleter);
+}
+
+// static
+void ScopedOSInfoOverride::deleter(base::win::OSInfo* info) {
+  delete info;
+}
+
+}  // namespace test
+}  // namespace base
diff --git a/base/test/scoped_os_info_override_win.h b/base/test/scoped_os_info_override_win.h
new file mode 100644
index 0000000..256c3b3
--- /dev/null
+++ b/base/test/scoped_os_info_override_win.h
@@ -0,0 +1,60 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_TEST_SCOPED_OS_INFO_OVERRIDE_WIN_H_
+#define BASE_TEST_SCOPED_OS_INFO_OVERRIDE_WIN_H_
+
+#include <memory>
+
+#include "base/macros.h"
+
+namespace base {
+namespace win {
+class OSInfo;
+}  // namespace win
+}  // namespace base
+
+namespace base {
+namespace test {
+
+// Helper class to override info returned by base::win::OSInfo::GetIntance()
+// for the lifetime of this object. Upon destruction, the original info at time
+// of object creation is restored.
+class ScopedOSInfoOverride {
+ public:
+  // Types of windows machines that can be used for overriding.  Add new
+  // machine types as needed.
+  enum class Type {
+    kWin10Pro,
+    kWin10Home,
+  };
+
+  explicit ScopedOSInfoOverride(Type type);
+  ~ScopedOSInfoOverride();
+
+ private:
+  using UniqueOsInfo =
+      std::unique_ptr<base::win::OSInfo, void (*)(base::win::OSInfo*)>;
+
+  static UniqueOsInfo CreateInfoOfType(Type type);
+
+  // The OSInfo taken by this instance at construction and restored at
+  // destruction.
+  base::win::OSInfo* original_info_;
+
+  // The OSInfo owned by this scoped object and which overrides
+  // base::win::OSInfo::GetIntance() for the lifespan of the object.
+  UniqueOsInfo overriding_info_;
+
+  // Because the dtor of OSInfo is private, a custom deleter is needed to use
+  // unique_ptr.
+  static void deleter(base::win::OSInfo* info);
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedOSInfoOverride);
+};
+
+}  // namespace test
+}  // namespace base
+
+#endif  // BASE_TEST_SCOPED_OS_INFO_OVERRIDE_WIN_H_
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index d33f244..37a153c 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -121,6 +121,36 @@
   return false;
 }
 
+bool* GetDomainEnrollmentStateStorage() {
+  static bool state = IsOS(OS_DOMAINMEMBER);
+  return &state;
+}
+
+bool* GetRegisteredWithManagementStateStorage() {
+  static bool state = []() {
+    ScopedNativeLibrary library(
+        FilePath(FILE_PATH_LITERAL("MDMRegistration.dll")));
+    if (!library.is_valid())
+      return false;
+
+    using IsDeviceRegisteredWithManagementFunction =
+        decltype(&::IsDeviceRegisteredWithManagement);
+    IsDeviceRegisteredWithManagementFunction
+        is_device_registered_with_management_function =
+            reinterpret_cast<IsDeviceRegisteredWithManagementFunction>(
+                library.GetFunctionPointer("IsDeviceRegisteredWithManagement"));
+    if (!is_device_registered_with_management_function)
+      return false;
+
+    BOOL is_managed = FALSE;
+    HRESULT hr =
+        is_device_registered_with_management_function(&is_managed, 0, nullptr);
+    return SUCCEEDED(hr) && is_managed;
+  }();
+
+  return &state;
+}
+
 }  // namespace
 
 // Uses the Windows 10 WRL API's to query the current system state. The API's
@@ -529,44 +559,17 @@
   return is_tablet;
 }
 
-enum DomainEnrollmentState {UNKNOWN = -1, NOT_ENROLLED, ENROLLED};
-static volatile long int g_domain_state = UNKNOWN;
-
 bool IsEnrolledToDomain() {
-  // Doesn't make any sense to retry inside a user session because joining a
-  // domain will only kick in on a restart.
-  if (g_domain_state == UNKNOWN) {
-    ::InterlockedCompareExchange(&g_domain_state,
-                                 IsOS(OS_DOMAINMEMBER) ?
-                                     ENROLLED : NOT_ENROLLED,
-                                 UNKNOWN);
-  }
+  return *GetDomainEnrollmentStateStorage();
+}
 
-  return g_domain_state == ENROLLED;
+// This function is deprecated, prefer class ScopedDomainStateForTesting.
+void SetDomainStateForTesting(bool state) {
+  *GetDomainEnrollmentStateStorage() = state;
 }
 
 bool IsDeviceRegisteredWithManagement() {
-  static bool is_device_registered_with_management = []() {
-    ScopedNativeLibrary library(
-        FilePath(FILE_PATH_LITERAL("MDMRegistration.dll")));
-    if (!library.is_valid())
-      return false;
-
-    using IsDeviceRegisteredWithManagementFunction =
-        decltype(&::IsDeviceRegisteredWithManagement);
-    IsDeviceRegisteredWithManagementFunction
-        is_device_registered_with_management_function =
-            reinterpret_cast<IsDeviceRegisteredWithManagementFunction>(
-                library.GetFunctionPointer("IsDeviceRegisteredWithManagement"));
-    if (!is_device_registered_with_management_function)
-      return false;
-
-    BOOL is_managed = false;
-    HRESULT hr =
-        is_device_registered_with_management_function(&is_managed, 0, nullptr);
-    return SUCCEEDED(hr) && is_managed;
-  }();
-  return is_device_registered_with_management;
+  return *GetRegisteredWithManagementStateStorage();
 }
 
 bool IsEnterpriseManaged() {
@@ -579,10 +582,6 @@
   return IsEnrolledToDomain();
 }
 
-void SetDomainStateForTesting(bool state) {
-  g_domain_state = state ? ENROLLED : NOT_ENROLLED;
-}
-
 bool IsUser32AndGdi32Available() {
   static auto is_user32_and_gdi32_available = []() {
     // If win32k syscalls aren't disabled, then user32 and gdi32 are available.
@@ -705,5 +704,25 @@
   }
 }
 
+ScopedDomainStateForTesting::ScopedDomainStateForTesting(bool state)
+    : initial_state_(IsEnrolledToDomain()) {
+  *GetDomainEnrollmentStateStorage() = state;
+}
+
+ScopedDomainStateForTesting::~ScopedDomainStateForTesting() {
+  *GetDomainEnrollmentStateStorage() = initial_state_;
+}
+
+ScopedDeviceRegisteredWithManagementForTesting::
+    ScopedDeviceRegisteredWithManagementForTesting(bool state)
+    : initial_state_(IsDeviceRegisteredWithManagement()) {
+  *GetRegisteredWithManagementStateStorage() = state;
+}
+
+ScopedDeviceRegisteredWithManagementForTesting::
+    ~ScopedDeviceRegisteredWithManagementForTesting() {
+  *GetRegisteredWithManagementStateStorage() = initial_state_;
+}
+
 }  // namespace win
 }  // namespace base
diff --git a/base/win/win_util.h b/base/win/win_util.h
index 8bc5b8e5..4303d95 100644
--- a/base/win/win_util.h
+++ b/base/win/win_util.h
@@ -29,6 +29,7 @@
 #include <vector>
 
 #include "base/base_export.h"
+#include "base/macros.h"
 #include "base/strings/string16.h"
 
 struct IPropertyStore;
@@ -164,6 +165,7 @@
 
 // Used by tests to mock any wanted state. Call with |state| set to true to
 // simulate being in a domain and false otherwise.
+// This function is deprecated, prefer class ScopedDomainStateForTesting below.
 BASE_EXPORT void SetDomainStateForTesting(bool state);
 
 // Returns true if the current process can make USER32 or GDI32 calls such as
@@ -192,6 +194,30 @@
 // Enable high-DPI support for the current process.
 BASE_EXPORT void EnableHighDPISupport();
 
+// Allows changing the domain enrolled state for the life time of the object.
+// The original state is restored upon destruction.
+class BASE_EXPORT ScopedDomainStateForTesting {
+ public:
+  ScopedDomainStateForTesting(bool state);
+  ~ScopedDomainStateForTesting();
+
+ private:
+  bool initial_state_;
+  DISALLOW_COPY_AND_ASSIGN(ScopedDomainStateForTesting);
+};
+
+// Allows changing the management registration state for the life time of the
+// object.  The original state is restored upon destruction.
+class BASE_EXPORT ScopedDeviceRegisteredWithManagementForTesting {
+ public:
+  ScopedDeviceRegisteredWithManagementForTesting(bool state);
+  ~ScopedDeviceRegisteredWithManagementForTesting();
+
+ private:
+  bool initial_state_;
+  DISALLOW_COPY_AND_ASSIGN(ScopedDeviceRegisteredWithManagementForTesting);
+};
+
 }  // namespace win
 }  // namespace base
 
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc
index a74c80a02..6fc31850 100644
--- a/base/win/windows_version.cc
+++ b/base/win/windows_version.cc
@@ -120,29 +120,45 @@
 }  // namespace
 
 // static
-OSInfo* OSInfo::GetInstance() {
+OSInfo** OSInfo::GetInstanceStorage() {
   // Note: we don't use the Singleton class because it depends on AtExitManager,
-  // and it's convenient for other modules to use this classs without it. This
-  // pattern is copied from gurl.cc.
-  static OSInfo* info;
-  if (!info) {
-    OSInfo* new_info = new OSInfo();
-    if (InterlockedCompareExchangePointer(
-        reinterpret_cast<PVOID*>(&info), new_info, NULL)) {
-      delete new_info;
+  // and it's convenient for other modules to use this class without it.
+  static OSInfo* info = []() {
+    _OSVERSIONINFOEXW version_info = {sizeof(version_info)};
+    ::GetVersionEx(reinterpret_cast<_OSVERSIONINFOW*>(&version_info));
+
+    _SYSTEM_INFO system_info = {};
+    ::GetNativeSystemInfo(&system_info);
+
+    DWORD os_type = 0;
+    if (version_info.dwMajorVersion == 6 || version_info.dwMajorVersion == 10) {
+      // Only present on Vista+.
+      GetProductInfoPtr get_product_info =
+          reinterpret_cast<GetProductInfoPtr>(::GetProcAddress(
+              ::GetModuleHandle(L"kernel32.dll"), "GetProductInfo"));
+      get_product_info(version_info.dwMajorVersion, version_info.dwMinorVersion,
+                       0, 0, &os_type);
     }
-  }
-  return info;
+
+    return new OSInfo(version_info, system_info, os_type);
+  }();
+
+  return &info;
 }
 
-OSInfo::OSInfo()
+// static
+OSInfo* OSInfo::GetInstance() {
+  return *GetInstanceStorage();
+}
+
+OSInfo::OSInfo(const _OSVERSIONINFOEXW& version_info,
+               const _SYSTEM_INFO& system_info,
+               int os_type)
     : version_(VERSION_PRE_XP),
       kernel32_version_(VERSION_PRE_XP),
       got_kernel32_version_(false),
       architecture_(OTHER_ARCHITECTURE),
       wow64_status_(GetWOW64StatusForProcess(GetCurrentProcess())) {
-  OSVERSIONINFOEX version_info = { sizeof version_info };
-  ::GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
   version_number_.major = version_info.dwMajorVersion;
   version_number_.minor = version_info.dwMinorVersion;
   version_number_.build = version_info.dwBuildNumber;
@@ -153,8 +169,6 @@
   service_pack_.minor = version_info.wServicePackMinor;
   service_pack_str_ = base::WideToUTF8(version_info.szCSDVersion);
 
-  SYSTEM_INFO system_info = {};
-  ::GetNativeSystemInfo(&system_info);
   switch (system_info.wProcessorArchitecture) {
     case PROCESSOR_ARCHITECTURE_INTEL: architecture_ = X86_ARCHITECTURE; break;
     case PROCESSOR_ARCHITECTURE_AMD64: architecture_ = X64_ARCHITECTURE; break;
@@ -163,16 +177,8 @@
   processors_ = system_info.dwNumberOfProcessors;
   allocation_granularity_ = system_info.dwAllocationGranularity;
 
-  GetProductInfoPtr get_product_info;
-  DWORD os_type;
-
   if (version_info.dwMajorVersion == 6 || version_info.dwMajorVersion == 10) {
     // Only present on Vista+.
-    get_product_info = reinterpret_cast<GetProductInfoPtr>(
-        ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "GetProductInfo"));
-
-    get_product_info(version_info.dwMajorVersion, version_info.dwMinorVersion,
-                     0, 0, &os_type);
     switch (os_type) {
       case PRODUCT_CLUSTER_SERVER:
       case PRODUCT_DATACENTER_SERVER:
diff --git a/base/win/windows_version.h b/base/win/windows_version.h
index 978df3d..22b9d00 100644
--- a/base/win/windows_version.h
+++ b/base/win/windows_version.h
@@ -13,6 +13,14 @@
 #include "base/macros.h"
 
 typedef void* HANDLE;
+struct _OSVERSIONINFOEXW;
+struct _SYSTEM_INFO;
+
+namespace base {
+namespace test {
+class ScopedOSInfoOverride;
+}  // namespace test
+}  // namespace base
 
 namespace base {
 namespace win {
@@ -116,7 +124,12 @@
   static WOW64Status GetWOW64StatusForProcess(HANDLE process_handle);
 
  private:
-  OSInfo();
+  friend class base::test::ScopedOSInfoOverride;
+  static OSInfo** GetInstanceStorage();
+
+  OSInfo(const _OSVERSIONINFOEXW& version_info,
+         const _SYSTEM_INFO& system_info,
+         int os_type);
   ~OSInfo();
 
   Version version_;
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 4b4b48c..233939c 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -2984,6 +2984,7 @@
     # TODO(agrieve): Enable lint for _has_sources rather than just _java_files.
     _lint_enabled = _java_files != [] && _supports_android && _chromium_code &&
                     !disable_android_lint
+
     if (_has_sources) {
       _compile_java_target = "${_main_target_name}__compile_java"
       compile_java(_compile_java_target) {
@@ -3175,11 +3176,15 @@
         deps = _accumulated_public_deps
       }
       _accumulated_public_deps += [ ":${target_name}__java_binary_script" ]
+    }
 
+    if (_is_java_binary ||
+        (_is_annotation_processor && !defined(_final_jar_path))) {
       group(target_name) {
         forward_variables_from(invoker,
                                [
                                  "data",
+                                 "deps",
                                  "data_deps",
                                  "visibility",
                                ])
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index fe53160..cc29276b 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -13,8 +13,11 @@
 #include <set>
 
 #include "base/containers/adapters.h"
+#include "base/debug/crash_logging.h"
+#include "base/debug/dump_without_crashing.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_argument.h"
@@ -853,8 +856,19 @@
 void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
   DCHECK(IsActiveTree());
   DCHECK(lifecycle().AllowsPropertyTreeAccess());
-  if (page_scale_factor()->SetCurrent(
-          ClampPageScaleFactorToLimits(active_page_scale))) {
+  float clamped_page_scale = ClampPageScaleFactorToLimits(active_page_scale);
+  // Temporary crash logging for https://crbug.com/845097.
+  static bool has_dumped_without_crashing = false;
+  if (host_impl_->settings().is_layer_tree_for_subframe &&
+      clamped_page_scale != 1.f && !has_dumped_without_crashing) {
+    has_dumped_without_crashing = true;
+    static auto* psf_oopif_error = base::debug::AllocateCrashKeyString(
+        "psf_oopif_error", base::debug::CrashKeySize::Size32);
+    base::debug::SetCrashKeyString(
+        psf_oopif_error, base::StringPrintf("%f", clamped_page_scale));
+    base::debug::DumpWithoutCrashing();
+  }
+  if (page_scale_factor()->SetCurrent(clamped_page_scale)) {
     DidUpdatePageScale();
     UpdatePageScaleNode();
   }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 794cfac4..4019d4d 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -273,6 +273,9 @@
     "//services/shape_detection/public/mojom:mojom_java",
     "//skia/public/interfaces:interfaces_java",
     "//third_party/android_data_chart:android_data_chart_java",
+    "//third_party/android_deps:com_google_dagger_dagger_android_java",
+    "//third_party/android_deps:com_google_dagger_dagger_java",
+    "//third_party/android_deps:javax_inject_javax_inject_java",
     "//third_party/android_media:android_media_java",
     "//third_party/android_protobuf:protobuf_nano_javalib",
     "//third_party/android_swipe_refresh:android_swipe_refresh_java",
@@ -365,6 +368,11 @@
   # Add the actual implementation where necessary so that downstream targets
   # can provide their own implementations.
   jar_excluded_patterns = [ "*/AppHooksImpl.class" ]
+
+  annotation_processor_deps = [
+    "//third_party/android_deps:dagger_processor",
+    "//third_party/android_deps:dagger_android_processor",
+  ]
 }
 
 action("chrome_android_java_google_api_keys_srcjar") {
diff --git a/chrome/android/java/res/layout/account_signin_view.xml b/chrome/android/java/res/layout/account_signin_view.xml
index 214499e..93bd18f 100644
--- a/chrome/android/java/res/layout/account_signin_view.xml
+++ b/chrome/android/java/res/layout/account_signin_view.xml
@@ -45,7 +45,7 @@
                     android:textAppearance="@style/BlackHeadline1"
                     android:text="@string/sign_in_to_chrome"/>
 
-                <View style="@style/Divider"/>
+                <View style="@style/HorizontalDivider"/>
 
                 <TextView
                     android:id="@+id/signin_choice_description"
@@ -112,7 +112,7 @@
                         android:maxLines="1"/>
                 </LinearLayout>
 
-                <View style="@style/Divider"/>
+                <View style="@style/HorizontalDivider"/>
 
                 <TextView
                     android:id="@+id/signin_sync_title"
@@ -138,7 +138,7 @@
                     android:textSize="@dimen/text_size_medium" />
 
                 <View
-                    style="@style/Divider"
+                    style="@style/HorizontalDivider"
                     android:layout_marginStart="56dp"
                     android:layout_marginEnd="16dp"/>
 
diff --git a/chrome/android/java/res/layout/data_reduction_main_menu_item.xml b/chrome/android/java/res/layout/data_reduction_main_menu_item.xml
index afdfa162..ad72178 100644
--- a/chrome/android/java/res/layout/data_reduction_main_menu_item.xml
+++ b/chrome/android/java/res/layout/data_reduction_main_menu_item.xml
@@ -12,7 +12,7 @@
 
     <View
         android:id="@+id/data_reduction_menu_divider"
-        style="@style/Divider" />
+        style="@style/HorizontalDivider" />
 
     <FrameLayout
         android:layout_width="match_parent"
diff --git a/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml b/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml
index a8d2b40d..1ced4e10 100644
--- a/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml
+++ b/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml
@@ -46,7 +46,7 @@
                     android:textAppearance="@style/BlackHeadline1"
                     android:text="@string/search_engine_dialog_title" />
 
-                <View style="@style/Divider" />
+                <View style="@style/HorizontalDivider" />
 
                 <org.chromium.chrome.browser.widget.RadioButtonLayout
                     android:id="@+id/default_search_engine_dialog_options"
diff --git a/chrome/android/java/res/layout/divider_preference.xml b/chrome/android/java/res/layout/divider_preference.xml
index a12b713..7035011 100644
--- a/chrome/android/java/res/layout/divider_preference.xml
+++ b/chrome/android/java/res/layout/divider_preference.xml
@@ -5,5 +5,5 @@
 
 <View 
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/Divider"
+    style="@style/HorizontalDivider"
     android:importantForAccessibility="no" />
diff --git a/chrome/android/java/res/layout/download_manager_date_separator.xml b/chrome/android/java/res/layout/download_manager_date_separator.xml
index 6e8dd67..d4983bdc 100644
--- a/chrome/android/java/res/layout/download_manager_date_separator.xml
+++ b/chrome/android/java/res/layout/download_manager_date_separator.xml
@@ -6,5 +6,5 @@
 
 <View
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/Divider"
+    style="@style/HorizontalDivider"
     android:minHeight="2dp" />
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/download_manager_section_separator.xml b/chrome/android/java/res/layout/download_manager_section_separator.xml
index 1f69e71..8429c86 100644
--- a/chrome/android/java/res/layout/download_manager_section_separator.xml
+++ b/chrome/android/java/res/layout/download_manager_section_separator.xml
@@ -11,7 +11,7 @@
     android:layout_height="wrap_content">
 
     <View
-        style="@style/Divider"
+        style="@style/HorizontalDivider"
         android:layout_marginStart="16dp" />
 
 </FrameLayout>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/download_manager_ui_space_widget.xml b/chrome/android/java/res/layout/download_manager_ui_space_widget.xml
index 4171d72f..687c5b0 100644
--- a/chrome/android/java/res/layout/download_manager_ui_space_widget.xml
+++ b/chrome/android/java/res/layout/download_manager_ui_space_widget.xml
@@ -48,7 +48,7 @@
     </LinearLayout>
 
     <View
-        style="@style/Divider"
+        style="@style/HorizontalDivider"
         android:layout_marginTop="@dimen/list_item_default_margin" />
 
 </LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/history_clear_browsing_data_header.xml b/chrome/android/java/res/layout/history_clear_browsing_data_header.xml
index 8057f65..a039afe 100644
--- a/chrome/android/java/res/layout/history_clear_browsing_data_header.xml
+++ b/chrome/android/java/res/layout/history_clear_browsing_data_header.xml
@@ -25,6 +25,6 @@
             android:textColor="@color/blue_when_enabled"
             android:textSize="@dimen/text_size_medium" />
 
-        <View style="@style/Divider" />
+        <View style="@style/HorizontalDivider" />
 
 </LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml b/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml
index 99d5d1c2..a28df8a 100644
--- a/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml
+++ b/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml
@@ -29,7 +29,7 @@
             android:layout_width="match_parent"
             android:layout_height="8dp" />
 
-        <View style="@style/Divider" />
+        <View style="@style/HorizontalDivider" />
 
     </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/icon_row_menu_footer.xml b/chrome/android/java/res/layout/icon_row_menu_footer.xml
index 2c7f986..02571a7 100644
--- a/chrome/android/java/res/layout/icon_row_menu_footer.xml
+++ b/chrome/android/java/res/layout/icon_row_menu_footer.xml
@@ -10,7 +10,7 @@
     android:layout_height="wrap_content"
     android:orientation="vertical" >
 
-    <View style="@style/Divider" />
+    <View style="@style/HorizontalDivider" />
 
     <LinearLayout
         android:layout_width="match_parent"
diff --git a/chrome/android/java/res/layout/password_accessory_sheet_divider.xml b/chrome/android/java/res/layout/password_accessory_sheet_divider.xml
index c91db6e..22ae257b 100644
--- a/chrome/android/java/res/layout/password_accessory_sheet_divider.xml
+++ b/chrome/android/java/res/layout/password_accessory_sheet_divider.xml
@@ -3,7 +3,7 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<View style="@style/Divider"
+<View style="@style/HorizontalDivider"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:paddingTop="8dp"
     android:paddingBottom="8dp" />
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/personalized_signin_promo_view_settings.xml b/chrome/android/java/res/layout/personalized_signin_promo_view_settings.xml
index 66a4038..6bee53d 100644
--- a/chrome/android/java/res/layout/personalized_signin_promo_view_settings.xml
+++ b/chrome/android/java/res/layout/personalized_signin_promo_view_settings.xml
@@ -48,7 +48,7 @@
         android:layout_height="wrap_content"/>
 
     <View
-        style="@style/Divider"
+        style="@style/HorizontalDivider"
         android:importantForAccessibility="no"/>
 </LinearLayout>
 
diff --git a/chrome/android/java/res/layout/signin_view.xml b/chrome/android/java/res/layout/signin_view.xml
index 7f4aed0..38b00c1 100644
--- a/chrome/android/java/res/layout/signin_view.xml
+++ b/chrome/android/java/res/layout/signin_view.xml
@@ -168,7 +168,7 @@
                 tools:text="@string/signin_google_services_description"/>
             <View
                 android:id="@+id/signin_divider"
-                style="@style/Divider"
+                style="@style/HorizontalDivider"
                 android:layout_below="@id/signin_google_services_description"
                 android:layout_marginStart="@dimen/signin_divider_margin_start"
                 android:layout_marginTop="20dp"
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml
index 07aee30..e16b76c 100644
--- a/chrome/android/java/res/values-v17/styles.xml
+++ b/chrome/android/java/res/values-v17/styles.xml
@@ -222,7 +222,7 @@
     </style>
 
     <!-- Dividers -->
-    <style name="Divider">
+    <style name="HorizontalDivider">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">@dimen/divider_height</item>
         <item name="android:background">@color/google_grey_300</item>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrViewContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrViewContainer.java
index f4a2b16..5fefb8a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrViewContainer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrViewContainer.java
@@ -16,7 +16,6 @@
 import android.view.ViewTreeObserver.OnPreDrawListener;
 import android.widget.FrameLayout;
 
-import org.chromium.base.BuildInfo;
 import org.chromium.base.TraceEvent;
 
 /**
@@ -70,14 +69,10 @@
             // linter from complaining about lockHardwareCanvas. This won't be reached pre-N
             // anyways.
             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return;
-            Canvas surfaceCanvas = null;
-            if (BuildInfo.isAtLeastP()) {
-                // This seems to have stopped crashing with Android P. It's >10x faster than the
-                // software canvas rendering for Android UI.
-                surfaceCanvas = mSurface.lockHardwareCanvas();
-            } else {
-                surfaceCanvas = mSurface.lockCanvas(null);
-            }
+            // This should be replaced with using HardwareCanvas once HardwareCanvas is more
+            // stable. HardwareCanvas can be >10x faster than the software canvas rendering
+            // for Android UI.
+            Canvas surfaceCanvas = mSurface.lockCanvas(null);
             surfaceCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
             drawSuper(surfaceCanvas);
             mSurface.unlockCanvasAndPost(surfaceCanvas);
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 4b47d3d..1f89c12f 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -326,7 +326,7 @@
         Your browsing data and activity, synced to your Google Account
       </message>
       <message name="IDS_PREFS_NONPERSONALIZED_SERVICES_SECTION_TITLE" desc="Title for the expandable group of preferences that control non-personalized Google services. This group contains preferences for data that is not tied to user's Google Account.">
-        Non-personalized services
+        Other Google services
       </message>
       <message name="IDS_PREFS_NONPERSONALIZED_SERVICES_SECTION_SUMMARY" desc="Summary for the expandable group of preferences that control non-personalized Google services. This group contains preferences for data that is not tied to user's Google Account.">
         Communicates with Google to improve browsing and Chrome
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 4ec1356..fd57a71 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -3517,7 +3517,7 @@
     Show sync settings
   </message>
   <message name="IDS_SETTINGS_NON_PERSONALIZED_SERVICES_SECTION_LABEL" desc="Title for a section that shows options for various Google services">
-    Non-personalized services
+    Other Google services
   </message>
   <message name="IDS_SETTINGS_NON_PERSONALIZED_SERVICES_SECTION_ACCESSIBILITY_LABEL" desc="Label for the button that toggles showing the google services settings. Only visible by screen reader software.">
     Show Google services settings
diff --git a/chrome/browser/extensions/bookmark_app_helper_unittest.cc b/chrome/browser/extensions/bookmark_app_helper_unittest.cc
index b41ca6b..d5735c4 100644
--- a/chrome/browser/extensions/bookmark_app_helper_unittest.cc
+++ b/chrome/browser/extensions/bookmark_app_helper_unittest.cc
@@ -419,6 +419,18 @@
     EXPECT_TRUE(extension);
     EXPECT_EQ(LAUNCH_CONTAINER_WINDOW,
               GetLaunchContainer(ExtensionPrefs::Get(profile()), extension));
+
+    // Mark the app as not locally installed and check that it now opens in a
+    // tab.
+    SetBookmarkAppIsLocallyInstalled(profile(), extension, false);
+    EXPECT_EQ(LAUNCH_CONTAINER_TAB,
+              GetLaunchContainer(ExtensionPrefs::Get(profile()), extension));
+
+    // Mark the app as locally installed and check that it now opens in a
+    // window.
+    SetBookmarkAppIsLocallyInstalled(profile(), extension, true);
+    EXPECT_EQ(LAUNCH_CONTAINER_WINDOW,
+              GetLaunchContainer(ExtensionPrefs::Get(profile()), extension));
   }
   {
     TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
diff --git a/chrome/browser/extensions/launch_util.cc b/chrome/browser/extensions/launch_util.cc
index c1ee50c..f95e525f 100644
--- a/chrome/browser/extensions/launch_util.cc
+++ b/chrome/browser/extensions/launch_util.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/extensions/extension_sync_service.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/web_applications/extensions/bookmark_app_util.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "components/pref_registry/pref_registry_syncable.h"
@@ -46,6 +47,12 @@
   if (value >= LAUNCH_TYPE_FIRST && value < NUM_LAUNCH_TYPES)
     result = static_cast<LaunchType>(value);
 
+  // Force hosted apps that are not locally installed to open in tabs.
+  if (extension->is_hosted_app() &&
+      !BookmarkAppIsLocallyInstalled(prefs, extension)) {
+    result = LAUNCH_TYPE_REGULAR;
+  }
+
 #if defined(OS_MACOSX)
   // Disable opening as window on Mac if:
   //  1. the extension isn't a platform app, AND
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc
index 3eea61c..bf4f327a 100644
--- a/chrome/browser/metrics/ukm_browsertest.cc
+++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -21,19 +21,27 @@
 #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_test.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/unified_consent/unified_consent_service_factory.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "components/browser_sync/profile_sync_service.h"
 #include "components/metrics_services_manager/metrics_services_manager.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/test/fake_server/fake_server_network_resources.h"
+#include "components/ukm/content/source_url_recorder.h"
 #include "components/ukm/ukm_service.h"
 #include "components/unified_consent/scoped_unified_consent.h"
 #include "components/variations/service/variations_field_trial_creator.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browsing_data_remover.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
 #include "content/public/test/browsing_data_remover_test_util.h"
+#include "content/public/test/navigation_handle_observer.h"
+#include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
 #include "services/metrics/public/cpp/ukm_source.h"
@@ -152,7 +160,22 @@
     // Can be non-zero only if UpdateUploadPermissions(true) has been called.
     return service->client_id_;
   }
-  bool HasDummySource(ukm::SourceId source_id) const {
+  ukm::UkmSource* GetSource(ukm::SourceId source_id) {
+    auto* service = ukm_service();
+    if (!service)
+      return nullptr;
+    auto it = service->sources().find(source_id);
+    return it == service->sources().end() ? nullptr : it->second.get();
+  }
+  ukm::UkmSource* NavigateAndGetSource(Browser* browser, const GURL& url) {
+    content::NavigationHandleObserver observer(
+        browser->tab_strip_model()->GetActiveWebContents(), url);
+    ui_test_utils::NavigateToURL(browser, url);
+    const ukm::SourceId source_id = ukm::ConvertToSourceId(
+        observer.navigation_id(), ukm::SourceIdType::NAVIGATION_ID);
+    return GetSource(source_id);
+  }
+  bool HasSource(ukm::SourceId source_id) const {
     auto* service = ukm_service();
     return service ? !!service->sources().count(source_id) : false;
   }
@@ -689,6 +712,114 @@
   CloseBrowserSynchronously(browser1);
 }
 
+IN_PROC_BROWSER_TEST_P(UkmBrowserTest, LogsTabId) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  MetricsConsentOverride metrics_consent(true);
+  Profile* profile = ProfileManager::GetActiveUserProfile();
+  std::unique_ptr<ProfileSyncServiceHarness> harness =
+      EnableSyncForProfile(profile);
+  Browser* sync_browser = CreateBrowser(profile);
+
+  const ukm::UkmSource* first_source = NavigateAndGetSource(
+      sync_browser, embedded_test_server()->GetURL("/title1.html"));
+
+  // Tab ids are incremented starting from 1. Since we started a new sync
+  // browser, this is the second tab.
+  EXPECT_EQ(2, first_source->navigation_data().tab_id);
+
+  // Ensure the tab id is constant in a single tab.
+  const ukm::UkmSource* second_source = NavigateAndGetSource(
+      sync_browser, embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_EQ(first_source->navigation_data().tab_id,
+            second_source->navigation_data().tab_id);
+
+  // Add a new tab, it should get a new tab id.
+  chrome::NewTab(sync_browser);
+  const ukm::UkmSource* third_source = NavigateAndGetSource(
+      sync_browser, embedded_test_server()->GetURL("/title3.html"));
+  EXPECT_EQ(3, third_source->navigation_data().tab_id);
+}
+
+IN_PROC_BROWSER_TEST_P(UkmBrowserTest, LogsPreviousSourceId) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  MetricsConsentOverride metrics_consent(true);
+  Profile* profile = ProfileManager::GetActiveUserProfile();
+  std::unique_ptr<ProfileSyncServiceHarness> harness =
+      EnableSyncForProfile(profile);
+  Browser* sync_browser = CreateBrowser(profile);
+
+  const ukm::UkmSource* first_source = NavigateAndGetSource(
+      sync_browser, embedded_test_server()->GetURL("/title1.html"));
+
+  const ukm::UkmSource* second_source = NavigateAndGetSource(
+      sync_browser, embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_EQ(first_source->id(),
+            second_source->navigation_data().previous_source_id);
+
+  // Open a new tab with window.open.
+  content::WebContents* opener =
+      sync_browser->tab_strip_model()->GetActiveWebContents();
+  GURL new_tab_url = embedded_test_server()->GetURL("/title3.html");
+  content::TestNavigationObserver waiter(new_tab_url);
+  waiter.StartWatchingNewWebContents();
+  EXPECT_TRUE(content::ExecuteScript(
+      opener, content::JsReplace("window.open($1)", new_tab_url)));
+  waiter.Wait();
+  EXPECT_NE(opener, sync_browser->tab_strip_model()->GetActiveWebContents());
+  ukm::SourceId new_id = ukm::GetSourceIdForWebContentsDocument(
+      sync_browser->tab_strip_model()->GetActiveWebContents());
+  ukm::UkmSource* new_tab_source = GetSource(new_id);
+  EXPECT_NE(nullptr, new_tab_source);
+  EXPECT_EQ(ukm::kInvalidSourceId,
+            new_tab_source->navigation_data().previous_source_id);
+
+  // Subsequent navigations within the tab should get a previous_source_id field
+  // set.
+  const ukm::UkmSource* subsequent_source = NavigateAndGetSource(
+      sync_browser, embedded_test_server()->GetURL("/title3.html"));
+  EXPECT_EQ(new_tab_source->id(),
+            subsequent_source->navigation_data().previous_source_id);
+}
+
+IN_PROC_BROWSER_TEST_P(UkmBrowserTest, LogsOpenerSource) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  MetricsConsentOverride metrics_consent(true);
+  Profile* profile = ProfileManager::GetActiveUserProfile();
+  std::unique_ptr<ProfileSyncServiceHarness> harness =
+      EnableSyncForProfile(profile);
+  Browser* sync_browser = CreateBrowser(profile);
+
+  const ukm::UkmSource* first_source = NavigateAndGetSource(
+      sync_browser, embedded_test_server()->GetURL("/title1.html"));
+  // This tab was not opened by another tab, so it should not have an opener
+  // id.
+  EXPECT_EQ(ukm::kInvalidSourceId,
+            first_source->navigation_data().opener_source_id);
+
+  // Open a new tab with window.open.
+  content::WebContents* opener =
+      sync_browser->tab_strip_model()->GetActiveWebContents();
+  GURL new_tab_url = embedded_test_server()->GetURL("/title2.html");
+  content::TestNavigationObserver waiter(new_tab_url);
+  waiter.StartWatchingNewWebContents();
+  EXPECT_TRUE(content::ExecuteScript(
+      opener, content::JsReplace("window.open($1)", new_tab_url)));
+  waiter.Wait();
+  EXPECT_NE(opener, sync_browser->tab_strip_model()->GetActiveWebContents());
+  ukm::SourceId new_id = ukm::GetSourceIdForWebContentsDocument(
+      sync_browser->tab_strip_model()->GetActiveWebContents());
+  ukm::UkmSource* new_tab_source = GetSource(new_id);
+  EXPECT_NE(nullptr, new_tab_source);
+  EXPECT_EQ(first_source->id(),
+            new_tab_source->navigation_data().opener_source_id);
+
+  // Subsequent navigations within the tab should not get an opener set.
+  const ukm::UkmSource* subsequent_source = NavigateAndGetSource(
+      sync_browser, embedded_test_server()->GetURL("/title3.html"));
+  EXPECT_EQ(ukm::kInvalidSourceId,
+            subsequent_source->navigation_data().opener_source_id);
+}
+
 // Make sure that UKM is disabled when an secondary passphrase is set.
 // Keep in sync with UkmTest.secondaryPassphraseCheck in
 // chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/
@@ -845,12 +976,12 @@
 
   const ukm::SourceId kDummySourceId = 0x54321;
   RecordDummySource(kDummySourceId);
-  EXPECT_TRUE(HasDummySource(kDummySourceId));
+  EXPECT_TRUE(HasSource(kDummySourceId));
 
   ClearBrowsingData(profile);
   // Other sources may already have been recorded since the data was cleared,
   // but the dummy source should be gone.
-  EXPECT_FALSE(HasDummySource(kDummySourceId));
+  EXPECT_FALSE(HasSource(kDummySourceId));
   // Client ID should NOT be reset.
   EXPECT_EQ(original_client_id, client_id());
   EXPECT_TRUE(ukm_enabled());
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js
index a5520db..a6c532b36 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.js
+++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -88,7 +88,6 @@
     /** @type {settings.SyncStatus} */
     syncStatus: {
       type: Object,
-      observer: 'onSyncStatusChanged_',
     },
 
     /**
@@ -130,6 +129,14 @@
     },
 
     /** @private */
+    signedIn_: {
+      type: Boolean,
+      value: true,
+      computed: 'computeSignedIn_(syncStatus.signedIn)',
+      observer: 'onSignedInChanged_',
+    },
+
+    /** @private */
     syncSectionDisabled_: {
       type: Boolean,
       value: false,
@@ -229,7 +236,15 @@
    * @return {boolean}
    * @private
    */
-  computeSyncSectionDisabled_() {
+  computeSignedIn_: function() {
+    return !!this.syncStatus.signedIn;
+  },
+
+  /**
+   * @return {boolean}
+   * @private
+   */
+  computeSyncSectionDisabled_: function() {
     return !!this.unifiedConsentEnabled &&
         (!this.syncStatus.signedIn || !!this.syncStatus.disabled ||
          (!!this.syncStatus.hasError &&
@@ -592,9 +607,12 @@
     settings.navigateTo(settings.routes.BASIC);
   },
 
-  /** @private */
-  onSyncStatusChanged_: function() {
-    this.syncSectionOpened_ = !!this.syncStatus.signedIn;
+  /**
+   * Collapses/Expands the sync section if the signedIn state has changed.
+   * @private
+   */
+  onSignedInChanged_: function() {
+    this.syncSectionOpened_ = !!this.signedIn_;
   },
 
   /**
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_util.cc b/chrome/browser/web_applications/extensions/bookmark_app_util.cc
index 5e424750..d75c643 100644
--- a/chrome/browser/web_applications/extensions/bookmark_app_util.cc
+++ b/chrome/browser/web_applications/extensions/bookmark_app_util.cc
@@ -34,9 +34,14 @@
 
 bool BookmarkAppIsLocallyInstalled(content::BrowserContext* context,
                                    const Extension* extension) {
+  return BookmarkAppIsLocallyInstalled(ExtensionPrefs::Get(context), extension);
+}
+
+bool BookmarkAppIsLocallyInstalled(const ExtensionPrefs* prefs,
+                                   const Extension* extension) {
   bool locally_installed;
-  if (ExtensionPrefs::Get(context)->ReadPrefAsBoolean(
-          extension->id(), kPrefLocallyInstalled, &locally_installed)) {
+  if (prefs->ReadPrefAsBoolean(extension->id(), kPrefLocallyInstalled,
+                               &locally_installed)) {
     return locally_installed;
   }
 
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_util.h b/chrome/browser/web_applications/extensions/bookmark_app_util.h
index 209488e..f8c94146 100644
--- a/chrome/browser/web_applications/extensions/bookmark_app_util.h
+++ b/chrome/browser/web_applications/extensions/bookmark_app_util.h
@@ -9,11 +9,13 @@
 class BrowserContext;
 }
 
-class Extension;
 class GURL;
 
 namespace extensions {
 
+class Extension;
+class ExtensionPrefs;
+
 // Sets an extension pref to indicate whether the hosted app is locally
 // installed or not. When apps are not locally installed they will appear in the
 // app launcher, but will act like normal web pages when launched. For example
@@ -29,6 +31,8 @@
 // Note this can be called for hosted apps which should use the default.
 bool BookmarkAppIsLocallyInstalled(content::BrowserContext* context,
                                    const Extension* extension);
+bool BookmarkAppIsLocallyInstalled(const ExtensionPrefs* prefs,
+                                   const Extension* extension);
 
 // Returns true if a bookmark or hosted app from a given URL is already
 // installed and enabled.
diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc
index 30a601f..c333a63 100644
--- a/chrome/installer/setup/install_worker.cc
+++ b/chrome/installer/setup/install_worker.cc
@@ -31,6 +31,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/version.h"
 #include "base/win/registry.h"
+#include "base/win/win_util.h"
+#include "base/win/windows_version.h"
 #include "chrome/install_static/install_details.h"
 #include "chrome/install_static/install_modes.h"
 #include "chrome/install_static/install_util.h"
@@ -638,6 +640,52 @@
                                true);  // overwrite version
 }
 
+void AddUpdateBrandCodeWorkItem(const InstallerState& installer_state,
+                                WorkItemList* install_list) {
+  // Only update specific brand codes needed for enterprise.
+  base::string16 brand;
+  if (!GoogleUpdateSettings::GetBrand(&brand))
+    return;
+
+  base::string16 new_brand = GetUpdatedBrandCode(brand);
+  if (new_brand.empty())
+    return;
+
+  // Only update if this machine is:
+  // - domain joined, or
+  // - registered with MDM and is not windows home edition
+  bool is_enterprise_version =
+      base::win::OSInfo::GetInstance()->version_type() != base::win::SUITE_HOME;
+  if (!(base::win::IsEnrolledToDomain() ||
+      (base::win::IsDeviceRegisteredWithManagement() &&
+       is_enterprise_version))) {
+    return;
+  }
+
+  BrowserDistribution* browser_dist = installer_state.product().distribution();
+  DCHECK(browser_dist);
+  install_list->AddSetRegValueWorkItem(
+      installer_state.root_key(), browser_dist->GetStateKey(), KEY_WOW64_32KEY,
+      google_update::kRegRLZBrandField, new_brand, true);
+}
+
+base::string16 GetUpdatedBrandCode(const base::string16& brand_code) {
+  // Brand codes to be remapped on enterprise installs.
+  static constexpr struct EnterpriseBrandRemapping {
+    const wchar_t* old_brand;
+    const wchar_t* new_brand;
+  } kEnterpriseBrandRemapping[] = {
+      {L"GGLS", L"GCEU"},
+      {L"GGRV", L"GCEV"},
+  };
+
+  for (auto mapping : kEnterpriseBrandRemapping) {
+    if (brand_code == mapping.old_brand)
+      return mapping.new_brand;
+  }
+  return base::string16();
+}
+
 bool AppendPostInstallTasks(const InstallerState& installer_state,
                             const base::FilePath& setup_path,
                             const base::Version* current_version,
@@ -857,6 +905,8 @@
   // Migrate usagestats back to Chrome.
   AddMigrateUsageStatsWorkItems(installer_state, install_list);
 
+  AddUpdateBrandCodeWorkItem(installer_state, install_list);
+
   // Append the tasks that run after the installation.
   AppendPostInstallTasks(installer_state,
                          setup_path,
diff --git a/chrome/installer/setup/install_worker.h b/chrome/installer/setup/install_worker.h
index aff102ec..4266352 100644
--- a/chrome/installer/setup/install_worker.h
+++ b/chrome/installer/setup/install_worker.h
@@ -46,6 +46,16 @@
                             bool add_language_identifier,
                             WorkItemList* list);
 
+// Updates the RLZ brand code or distribution tag.  This is called by the
+// installer to update deprecated, organic enterprise brand codes.
+void AddUpdateBrandCodeWorkItem(const InstallerState& installer_state,
+                                WorkItemList* install_list);
+
+// Checks to see if the given brand code is one that should be updated if
+// the current install is considered an enterprise install.  If so the updated
+// brand code is returned, otherwise an empty string is returned.
+base::string16 GetUpdatedBrandCode(const base::string16& brand_code);
+
 // After a successful copying of all the files, this function is called to
 // do a few post install tasks:
 // - Handle the case of in-use-update by updating "opv" (old version) key or
diff --git a/chrome/installer/setup/install_worker_unittest.cc b/chrome/installer/setup/install_worker_unittest.cc
index 1ab277e2..b989f28 100644
--- a/chrome/installer/setup/install_worker_unittest.cc
+++ b/chrome/installer/setup/install_worker_unittest.cc
@@ -6,10 +6,17 @@
 
 #include <memory>
 #include <string>
+#include <tuple>
 
+#include "base/strings/stringprintf.h"
+#include "base/test/scoped_os_info_override_win.h"
+#include "base/test/test_reg_util_win.h"
 #include "base/version.h"
 #include "base/win/registry.h"
+#include "base/win/win_util.h"
+#include "base/win/windows_version.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/install_static/test/scoped_install_details.h"
 #include "chrome/installer/setup/installer_state.h"
 #include "chrome/installer/setup/setup_util.h"
 #include "chrome/installer/util/create_reg_key_work_item.h"
@@ -43,8 +50,11 @@
 using ::testing::StrCaseEq;
 using ::testing::StrEq;
 using ::testing::StrictMock;
+using ::testing::TestParamInfo;
 using ::testing::Values;
 
+namespace {
+
 // Mock classes to help with testing
 //------------------------------------------------------------------------------
 
@@ -165,6 +175,75 @@
   }
 };
 
+void AddChromeToInstallationState(bool system_level,
+                                  base::Version* current_version,
+                                  MockInstallationState* installation_state) {
+  MockProductState product_state;
+  product_state.set_version(new base::Version(*current_version));
+  product_state.set_brand(L"TEST");
+  product_state.set_eula_accepted(1);
+  base::FilePath install_path = installer::GetChromeInstallPath(system_level);
+  product_state.SetUninstallProgram(
+      install_path.AppendASCII(current_version->GetString())
+          .Append(installer::kInstallerDir)
+          .Append(installer::kSetupExe));
+  product_state.AddUninstallSwitch(installer::switches::kUninstall);
+  if (system_level)
+    product_state.AddUninstallSwitch(installer::switches::kSystemLevel);
+
+  installation_state->SetProductState(system_level, product_state);
+}
+
+MockInstallationState* BuildChromeInstallationState(
+    bool system_level,
+    base::Version* current_version) {
+  std::unique_ptr<MockInstallationState> installation_state(
+      new MockInstallationState());
+  AddChromeToInstallationState(system_level, current_version,
+                               installation_state.get());
+  return installation_state.release();
+}
+
+MockInstallerState* BuildBasicInstallerState(
+    bool system_install,
+    const InstallationState& machine_state,
+    InstallerState::Operation operation) {
+  std::unique_ptr<MockInstallerState> installer_state(new MockInstallerState());
+
+  InstallerState::Level level = system_install ? InstallerState::SYSTEM_LEVEL
+                                               : InstallerState::USER_LEVEL;
+  installer_state->set_level(level);
+  installer_state->set_operation(operation);
+  // Hope this next one isn't checked for now.
+  installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH");
+  return installer_state.release();
+}
+
+void AddChromeToInstallerState(const InstallationState& machine_state,
+                               MockInstallerState* installer_state) {
+  // Fresh install or upgrade?
+  const ProductState* chrome =
+      machine_state.GetProductState(installer_state->system_install());
+  if (chrome) {
+    installer_state->AddProductFromState(*chrome);
+  } else {
+    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+    installer_state->AddProduct(std::make_unique<Product>(dist));
+  }
+}
+
+MockInstallerState* BuildChromeInstallerState(
+    bool system_install,
+    const InstallationState& machine_state,
+    InstallerState::Operation operation) {
+  std::unique_ptr<MockInstallerState> installer_state(
+      BuildBasicInstallerState(system_install, machine_state, operation));
+  AddChromeToInstallerState(machine_state, installer_state.get());
+  return installer_state.release();
+}
+
+}  // namespace
+
 // The test fixture
 //------------------------------------------------------------------------------
 
@@ -190,72 +269,6 @@
     temp_dir_ = base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123");
   }
 
-  void AddChromeToInstallationState(
-      bool system_level,
-      MockInstallationState* installation_state) {
-    MockProductState product_state;
-    product_state.set_version(new base::Version(*current_version_));
-    product_state.set_brand(L"TEST");
-    product_state.set_eula_accepted(1);
-    base::FilePath install_path = installer::GetChromeInstallPath(system_level);
-    product_state.SetUninstallProgram(
-      install_path.AppendASCII(current_version_->GetString())
-          .Append(installer::kInstallerDir)
-          .Append(installer::kSetupExe));
-    product_state.AddUninstallSwitch(installer::switches::kUninstall);
-    if (system_level)
-      product_state.AddUninstallSwitch(installer::switches::kSystemLevel);
-
-    installation_state->SetProductState(system_level, product_state);
-  }
-
-  MockInstallationState* BuildChromeInstallationState(bool system_level) {
-    std::unique_ptr<MockInstallationState> installation_state(
-        new MockInstallationState());
-    AddChromeToInstallationState(system_level, installation_state.get());
-    return installation_state.release();
-  }
-
-  static MockInstallerState* BuildBasicInstallerState(
-      bool system_install,
-      const InstallationState& machine_state,
-      InstallerState::Operation operation) {
-    std::unique_ptr<MockInstallerState> installer_state(
-        new MockInstallerState());
-
-    InstallerState::Level level = system_install ?
-        InstallerState::SYSTEM_LEVEL : InstallerState::USER_LEVEL;
-    installer_state->set_level(level);
-    installer_state->set_operation(operation);
-    // Hope this next one isn't checked for now.
-    installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH");
-    return installer_state.release();
-  }
-
-  static void AddChromeToInstallerState(
-      const InstallationState& machine_state,
-      MockInstallerState* installer_state) {
-    // Fresh install or upgrade?
-    const ProductState* chrome =
-        machine_state.GetProductState(installer_state->system_install());
-    if (chrome) {
-      installer_state->AddProductFromState(*chrome);
-    } else {
-      BrowserDistribution* dist = BrowserDistribution::GetDistribution();
-      installer_state->AddProduct(std::make_unique<Product>(dist));
-    }
-  }
-
-  static MockInstallerState* BuildChromeInstallerState(
-      bool system_install,
-      const InstallationState& machine_state,
-      InstallerState::Operation operation) {
-    std::unique_ptr<MockInstallerState> installer_state(
-        BuildBasicInstallerState(system_install, machine_state, operation));
-    AddChromeToInstallerState(machine_state, installer_state.get());
-    return installer_state.release();
-  }
-
  protected:
   std::unique_ptr<base::Version> current_version_;
   std::unique_ptr<base::Version> new_version_;
@@ -288,7 +301,7 @@
                                            WorkItem::kWow64Default));
 
   std::unique_ptr<InstallationState> installation_state(
-      BuildChromeInstallationState(system_level));
+      BuildChromeInstallationState(system_level, current_version_.get()));
 
   std::unique_ptr<InstallerState> installer_state(
       BuildChromeInstallerState(system_level, *installation_state,
@@ -317,3 +330,123 @@
                       *new_version_.get(),
                       &work_item_list);
 }
+
+// Tests for installer::AddUpdateBrandCodeWorkItem().
+//------------------------------------------------------------------------------
+
+// Parameters for AddUpdateBrandCodeWorkItem tests:
+//   bool: is domain joined
+//   bool: is registered with MDM
+//   bool: is Windows 10 home edition
+using AddUpdateBrandCodeWorkItemTestParams = std::tuple<bool, bool, bool>;
+
+// These tests run at system level.
+static const bool kSystemLevel = true;
+
+class AddUpdateBrandCodeWorkItemTest
+    : public ::testing::TestWithParam<AddUpdateBrandCodeWorkItemTestParams> {
+ public:
+  AddUpdateBrandCodeWorkItemTest()
+      : is_domain_joined_(std::get<0>(GetParam())),
+        is_registered_(std::get<1>(GetParam())),
+        is_home_edition_(std::get<2>(GetParam())),
+        scoped_install_details_(kSystemLevel),
+        current_version_(new base::Version("1.0.0.0")),
+        installation_state_(
+            BuildChromeInstallationState(kSystemLevel, current_version_.get())),
+        installer_state_(BuildChromeInstallerState(
+            kSystemLevel,
+            *installation_state_,
+            InstallerState::SINGLE_INSTALL_OR_UPDATE)),
+        scoped_domain_state_(is_domain_joined_),
+        scoped_registration_state_(is_registered_),
+        scoped_os_info_override_(
+            is_home_edition_
+                ? base::test::ScopedOSInfoOverride::Type::kWin10Home
+                : base::test::ScopedOSInfoOverride::Type::kWin10Pro) {}
+
+  void SetUp() override {
+    // Override registry so that tests don't mess up the machine's state.
+    ASSERT_NO_FATAL_FAILURE(registry_override_.OverrideRegistry(
+        HKEY_LOCAL_MACHINE, &registry_override_hklm_path_));
+  }
+
+  void SetupExpectations(const base::string16& brand,
+                         StrictMock<MockWorkItemList>* work_item_list) {
+    if (!brand.empty()) {
+      BrowserDistribution* browser_dist =
+          installer_state_->product().distribution();
+      DCHECK(browser_dist);
+      base::win::RegKey key(installer_state_->root_key(),
+                            browser_dist->GetStateKey().c_str(), KEY_WRITE);
+      ASSERT_TRUE(key.Valid());
+      ASSERT_EQ(
+          0, key.WriteValue(google_update::kRegRLZBrandField, brand.c_str()));
+    }
+
+    if (!installer::GetUpdatedBrandCode(brand).empty() &&
+        (is_domain_joined_ || (is_registered_ && !is_home_edition_))) {
+      EXPECT_CALL(*work_item_list,
+                  AddSetRegStringValueWorkItem(_, _, _, _, _, _))
+          .WillOnce(Return(nullptr));  // Return value ignored.
+    }
+  }
+
+  const InstallerState* installer_state() { return installer_state_.get(); }
+
+ private:
+  const bool is_domain_joined_;
+  const bool is_registered_;
+  const bool is_home_edition_;
+
+  install_static::ScopedInstallDetails scoped_install_details_;
+  std::unique_ptr<base::Version> current_version_;
+  std::unique_ptr<InstallationState> installation_state_;
+  std::unique_ptr<InstallerState> installer_state_;
+  registry_util::RegistryOverrideManager registry_override_;
+  base::string16 registry_override_hklm_path_;
+  base::win::ScopedDomainStateForTesting scoped_domain_state_;
+  base::win::ScopedDeviceRegisteredWithManagementForTesting
+      scoped_registration_state_;
+  base::test::ScopedOSInfoOverride scoped_os_info_override_;
+};
+
+TEST_P(AddUpdateBrandCodeWorkItemTest, NoBrand) {
+  StrictMock<MockWorkItemList> work_item_list;
+  SetupExpectations(L"", &work_item_list);
+  installer::AddUpdateBrandCodeWorkItem(*installer_state(), &work_item_list);
+}
+
+TEST_P(AddUpdateBrandCodeWorkItemTest, GGRV) {
+  StrictMock<MockWorkItemList> work_item_list;
+  SetupExpectations(L"GGRV", &work_item_list);
+  installer::AddUpdateBrandCodeWorkItem(*installer_state(), &work_item_list);
+}
+
+TEST_P(AddUpdateBrandCodeWorkItemTest, GGLS) {
+  StrictMock<MockWorkItemList> work_item_list;
+  SetupExpectations(L"GGLS", &work_item_list);
+  installer::AddUpdateBrandCodeWorkItem(*installer_state(), &work_item_list);
+}
+
+TEST_P(AddUpdateBrandCodeWorkItemTest, TEST) {
+  StrictMock<MockWorkItemList> work_item_list;
+  SetupExpectations(L"TEST", &work_item_list);
+  installer::AddUpdateBrandCodeWorkItem(*installer_state(), &work_item_list);
+}
+
+struct AddUpdateBrandCodeWorkItemTestParamToString {
+  std::string operator()(
+      const TestParamInfo<AddUpdateBrandCodeWorkItemTestParams>& info) const {
+    const char* joined = std::get<0>(info.param) ? "joined" : "notjoined";
+    const char* registered =
+        std::get<1>(info.param) ? "registered" : "notregistered";
+    const char* home = std::get<2>(info.param) ? "home" : "nothome";
+    return base::StringPrintf("%s_%s_%s", joined, registered, home);
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(AddUpdateBrandCodeWorkItemTest,
+                        AddUpdateBrandCodeWorkItemTest,
+                        Combine(Bool(), Bool(), Bool()),
+                        AddUpdateBrandCodeWorkItemTestParamToString());
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js
index 41440ce8..749436f 100644
--- a/chrome/test/data/webui/settings/people_page_sync_page_test.js
+++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -195,6 +195,19 @@
       Polymer.dom.flush();
       assertFalse(ironCollapse.opened);
       assertFalse(expandIcon.expanded);
+
+      // Random changes to syncStatus should not expand the section.
+      // Regression test for https://crbug.com/869938
+      syncPage.syncStatus = {
+        signedIn: true,
+        disabled: false,
+        hasError: false,
+        statusAction: settings.StatusAction.NO_ACTION,
+        statusText: 'UninterestingChange',  // Dummy change to trigger observer.
+      };
+      assertFalse(ironCollapse.opened);
+      assertFalse(expandIcon.expanded);
+
       syncSectionToggle.click();
       Polymer.dom.flush();
       assertTrue(ironCollapse.opened);
@@ -213,6 +226,44 @@
       assertTrue(ironCollapse.hidden);
     });
 
+    test('SyncSectionLayout_UnifiedConsentEnabled_SignoutCollapse', function() {
+      const ironCollapse = syncPage.$$('#sync-section');
+      const syncSectionToggle = syncPage.$$('#sync-section-toggle');
+      const expandIcon = syncSectionToggle.querySelector('cr-expand-button');
+      syncPage.syncStatus = {
+        signedIn: true,
+        disabled: false,
+        hasError: false,
+        statusAction: settings.StatusAction.NO_ACTION,
+      };
+      syncPage.unifiedConsentEnabled = true;
+      Polymer.dom.flush();
+
+      // Sync section is initially open when signed in.
+      assertTrue(ironCollapse.opened);
+      assertTrue(expandIcon.expanded);
+
+      // Signout collapses the section.
+      syncPage.syncStatus = {
+        signedIn: false,
+        disabled: false,
+        hasError: false,
+        statusAction: settings.StatusAction.NO_ACTION,
+      };
+      assertFalse(ironCollapse.opened);
+      assertFalse(expandIcon.expanded);
+
+      // Signin expands the section.
+      syncPage.syncStatus = {
+        signedIn: true,
+        disabled: false,
+        hasError: false,
+        statusAction: settings.StatusAction.NO_ACTION,
+      };
+      assertTrue(ironCollapse.opened);
+      assertTrue(expandIcon.expanded);
+    });
+
     test('SyncSectionLayout_UnifiedConsentEnabled_SignedOut', function() {
       const ironCollapse = syncPage.$$('#sync-section');
       const syncSectionToggle = syncPage.$$('#sync-section-toggle');
diff --git a/chromecast/browser/test/cast_features_browsertest.cc b/chromecast/browser/test/cast_features_browsertest.cc
index 0e2b181..a4c3dea 100644
--- a/chromecast/browser/test/cast_features_browsertest.cc
+++ b/chromecast/browser/test/cast_features_browsertest.cc
@@ -39,7 +39,7 @@
 //
 //      IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_PRE_TestFoo) {
 //        // Reset the state of the features.
-//        CleareFeaturesFromPrefs({kFooFeature1, kFooFeature2});
+//        ClearFeaturesFromPrefs({kFooFeature1, kFooFeature2});
 //      }
 //
 //      IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_TestFoo) {
@@ -159,13 +159,13 @@
 
 // Test that set features activate on the next boot. Part 1 of 3.
 IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
-                       PRE_PRE_TestFeaturesActivateOnBoot) {
+                       DISABLED_PRE_PRE_TestFeaturesActivateOnBoot) {
   ClearFeaturesFromPrefs({kTestFeat1, kTestFeat2, kTestFeat3, kTestFeat4});
 }
 
 // Test that set features activate on the next boot. Part 2 of 3.
 IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
-                       PRE_TestFeaturesActivateOnBoot) {
+                       DISABLED_PRE_TestFeaturesActivateOnBoot) {
   // Default values should be returned.
   ASSERT_FALSE(chromecast::IsFeatureEnabled(kTestFeat1));
   ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat2));
@@ -186,7 +186,8 @@
 }
 
 // Test that features activate on the next boot. Part 3 of 3.
-IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, TestFeaturesActivateOnBoot) {
+IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
+                       DISABLED_TestFeaturesActivateOnBoot) {
   // Overriden values set in test case above should be set.
   ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat1));
   ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat2));
@@ -196,12 +197,13 @@
 
 // Test that features with params activate on boot. Part 1 of 3.
 IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
-                       PRE_PRE_TestParamsActivateOnBoot) {
+                       DISABLED_PRE_PRE_TestParamsActivateOnBoot) {
   ClearFeaturesFromPrefs({kTestFeat11});
 }
 
 // Test that features with params activate on boot. Part 2 of 3.
-IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_TestParamsActivateOnBoot) {
+IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
+                       DISABLED_PRE_TestParamsActivateOnBoot) {
   // Default value should be returned.
   ASSERT_FALSE(chromecast::IsFeatureEnabled(kTestFeat11));
 
@@ -221,7 +223,8 @@
 }
 
 // Test that features with params activate on boot. Part 3 of 3.
-IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, TestParamsActivateOnBoot) {
+IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
+                       DISABLED_TestParamsActivateOnBoot) {
   // Check that the feature is now enabled.
   ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat11));
 
@@ -245,13 +248,13 @@
 
 // Test that only well-formed features are persisted to disk. Part 1 of 3.
 IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
-                       PRE_PRE_TestOnlyWellFormedFeaturesPersisted) {
+                       DISABLED_PRE_PRE_TestOnlyWellFormedFeaturesPersisted) {
   ClearFeaturesFromPrefs({kTestFeat21, kTestFeat22, kTestFeat23, kTestFeat24});
 }
 
 // Test that only well-formed features are persisted to disk. Part 2 of 3.
 IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
-                       PRE_TestOnlyWellFormedFeaturesPersisted) {
+                       DISABLED_PRE_TestOnlyWellFormedFeaturesPersisted) {
   // Default values should be returned.
   ASSERT_FALSE(chromecast::IsFeatureEnabled(kTestFeat21));
   ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat22));
@@ -272,7 +275,7 @@
 
 // Test that only well-formed features are persisted to disk. Part 2 of 2.
 IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest,
-                       TestOnlyWellFormedFeaturesPersisted) {
+                       DISABLED_TestOnlyWellFormedFeaturesPersisted) {
   // Only the well-formed parameters should be overriden.
   ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat21));
   ASSERT_FALSE(chromecast::IsFeatureEnabled(kTestFeat24));
diff --git a/components/autofill/content/renderer/html_based_username_detector.cc b/components/autofill/content/renderer/html_based_username_detector.cc
index b4de22ec..c681e5c 100644
--- a/components/autofill/content/renderer/html_based_username_detector.cc
+++ b/components/autofill/content/renderer/html_based_username_detector.cc
@@ -210,14 +210,10 @@
       kNegativeLatin, kNegativeLatinSize, kNegativeNonLatin,
       kNegativeNonLatinSize};
 
-  possible_usernames_data->erase(
-      std::remove_if(possible_usernames_data->begin(),
-                     possible_usernames_data->end(),
-                     [](const UsernameFieldData& possible_username) {
-                       return ContainsWordFromCategory(possible_username,
-                                                       kNegativeCategory);
-                     }),
-      possible_usernames_data->end());
+  base::EraseIf(
+      *possible_usernames_data, [](const UsernameFieldData& possible_username) {
+        return ContainsWordFromCategory(possible_username, kNegativeCategory);
+      });
 }
 
 // Check if any word from the given category (|category|) appears in fields from
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index e725eb0..35a63cd 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -404,14 +404,10 @@
   // the list of datalist values.
   std::set<base::string16> data_list_set(data_list_values_.begin(),
                                          data_list_values_.end());
-  suggestions->erase(
-      std::remove_if(
-          suggestions->begin(), suggestions->end(),
-          [&data_list_set](const Suggestion& suggestion) {
-            return suggestion.frontend_id == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY &&
-                   base::ContainsKey(data_list_set, suggestion.value);
-          }),
-      suggestions->end());
+  base::EraseIf(*suggestions, [&data_list_set](const Suggestion& suggestion) {
+    return suggestion.frontend_id == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY &&
+           base::ContainsKey(data_list_set, suggestion.value);
+  });
 
 #if !defined(OS_ANDROID)
   // Insert the separator between the datalist and Autofill/Autocomplete values
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 02e8237..079018b 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1705,9 +1705,7 @@
     return;
 
   // Remove empty profiles from input.
-  profiles->erase(std::remove_if(profiles->begin(), profiles->end(),
-                                 IsEmptyFunctor<AutofillProfile>(app_locale_)),
-                  profiles->end());
+  base::EraseIf(*profiles, IsEmptyFunctor<AutofillProfile>(app_locale_));
 
   if (!database_helper_->GetLocalDatabase())
     return;
@@ -1748,9 +1746,7 @@
     return;
 
   // Remove empty credit cards from input.
-  credit_cards->erase(std::remove_if(credit_cards->begin(), credit_cards->end(),
-                                     IsEmptyFunctor<CreditCard>(app_locale_)),
-                      credit_cards->end());
+  base::EraseIf(*credit_cards, IsEmptyFunctor<CreditCard>(app_locale_));
 
   if (!database_helper_->GetLocalDatabase())
     return;
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 1aa7a05..e79be32 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -155,7 +155,7 @@
 // Controls whether password generation is offered automatically on fields
 // percieved as eligible for generation.
 const base::Feature kAutomaticPasswordGeneration = {
-    "AutomaticPasswordGeneration", base::FEATURE_DISABLED_BY_DEFAULT};
+    "AutomaticPasswordGeneration", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Controls whether or not the autofill UI triggers on a single click.
 const base::Feature kSingleClickAutofill{"SingleClickAutofill",
diff --git a/components/certificate_transparency/chrome_require_ct_delegate.cc b/components/certificate_transparency/chrome_require_ct_delegate.cc
index f5361dc..f6f6eb4d 100644
--- a/components/certificate_transparency/chrome_require_ct_delegate.cc
+++ b/components/certificate_transparency/chrome_require_ct_delegate.cc
@@ -208,17 +208,13 @@
   ParseSpkiHashes(excluded_legacy_spkis, &legacy_spkis_);
 
   // Filter out SPKIs that aren't for legacy CAs.
-  legacy_spkis_.erase(
-      std::remove_if(legacy_spkis_.begin(), legacy_spkis_.end(),
-                     [](const net::HashValue& hash) {
-                       if (!net::IsLegacyPubliclyTrustedCA(hash)) {
-                         LOG(ERROR) << "Non-legacy SPKI configured "
-                                    << hash.ToString();
-                         return true;
-                       }
-                       return false;
-                     }),
-      legacy_spkis_.end());
+  base::EraseIf(legacy_spkis_, [](const net::HashValue& hash) {
+    if (!net::IsLegacyPubliclyTrustedCA(hash)) {
+      LOG(ERROR) << "Non-legacy SPKI configured " << hash.ToString();
+      return true;
+    }
+    return false;
+  });
 }
 
 bool ChromeRequireCTDelegate::MatchHostname(const std::string& hostname,
diff --git a/components/crash/content/app/minidump_with_crashpad_info.cc b/components/crash/content/app/minidump_with_crashpad_info.cc
index 50f41a2..845da1a 100644
--- a/components/crash/content/app/minidump_with_crashpad_info.cc
+++ b/components/crash/content/app/minidump_with_crashpad_info.cc
@@ -5,6 +5,7 @@
 #include "components/crash/content/app/minidump_with_crashpad_info.h"
 
 #include "base/files/file_util.h"
+#include "base/stl_util.h"
 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
 #include "third_party/crashpad/crashpad/client/crashpad_info.h"
 #include "third_party/crashpad/crashpad/client/settings.h"
@@ -74,11 +75,9 @@
 
   // Start by removing any unused directory entries.
   // TODO(siggi): Fix Crashpad to ignore unused streams.
-  directory_.erase(std::remove_if(directory_.begin(), directory_.end(),
-                                  [](const MINIDUMP_DIRECTORY& entry) {
-                                    return entry.StreamType == UnusedStream;
-                                  }),
-                   directory_.end());
+  base::EraseIf(directory_, [](const MINIDUMP_DIRECTORY& entry) {
+    return entry.StreamType == UnusedStream;
+  });
 
   // Update the header.
   // TODO(siggi): Fix Crashpad's version checking.
diff --git a/components/crash/content/app/run_as_crashpad_handler_win.cc b/components/crash/content/app/run_as_crashpad_handler_win.cc
index c3b7fd9c..7013c90 100644
--- a/components/crash/content/app/run_as_crashpad_handler_win.cc
+++ b/components/crash/content/app/run_as_crashpad_handler_win.cc
@@ -12,6 +12,7 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/process/memory.h"
+#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/browser_watcher/stability_report_user_stream_data_source.h"
@@ -52,17 +53,14 @@
       base::string16(L"--") + base::UTF8ToUTF16(process_type_switch) + L"=";
   const base::string16 user_data_dir_arg_prefix =
       base::string16(L"--") + base::UTF8ToUTF16(user_data_dir_switch) + L"=";
-  argv.erase(
-      std::remove_if(argv.begin(), argv.end(),
-                     [&process_type_arg_prefix,
-                      &user_data_dir_arg_prefix](const base::string16& str) {
-                       return base::StartsWith(str, process_type_arg_prefix,
-                                               base::CompareCase::SENSITIVE) ||
-                              base::StartsWith(str, user_data_dir_arg_prefix,
-                                               base::CompareCase::SENSITIVE) ||
-                              (!str.empty() && str[0] == L'/');
-                     }),
-      argv.end());
+  base::EraseIf(argv, [&process_type_arg_prefix,
+                       &user_data_dir_arg_prefix](const base::string16& str) {
+    return base::StartsWith(str, process_type_arg_prefix,
+                            base::CompareCase::SENSITIVE) ||
+           base::StartsWith(str, user_data_dir_arg_prefix,
+                            base::CompareCase::SENSITIVE) ||
+           (!str.empty() && str[0] == L'/');
+  });
 
   std::unique_ptr<char* []> argv_as_utf8(new char*[argv.size() + 1]);
   std::vector<std::string> storage;
diff --git a/components/cronet/ios/cronet_environment.mm b/components/cronet/ios/cronet_environment.mm
index 82d66560..31642bc 100644
--- a/components/cronet/ios/cronet_environment.mm
+++ b/components/cronet/ios/cronet_environment.mm
@@ -377,9 +377,8 @@
   // of changing it.
   [[NSHTTPCookieStorage sharedHTTPCookieStorage]
       setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
-  std::unique_ptr<net::CookieStore> cookie_store =
-      std::make_unique<net::CookieStoreIOS>(
-          [NSHTTPCookieStorage sharedHTTPCookieStorage]);
+  auto cookie_store = std::make_unique<net::CookieStoreIOS>(
+      [NSHTTPCookieStorage sharedHTTPCookieStorage], nullptr /* net_log */);
   context_builder.SetCookieAndChannelIdStores(std::move(cookie_store), nullptr);
 
   context_builder.set_enable_brotli(brotli_enabled_);
diff --git a/components/cryptauth/fake_connection.cc b/components/cryptauth/fake_connection.cc
index 6303d27..f3f5de3 100644
--- a/components/cryptauth/fake_connection.cc
+++ b/components/cryptauth/fake_connection.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/callback.h"
+#include "base/stl_util.h"
 #include "components/cryptauth/wire_message.h"
 
 namespace cryptauth {
@@ -49,9 +50,7 @@
 }
 
 void FakeConnection::RemoveObserver(ConnectionObserver* observer) {
-  observers_.erase(
-      std::remove(observers_.begin(), observers_.end(), observer),
-      observers_.end());
+  base::Erase(observers_, observer);
   Connection::RemoveObserver(observer);
 }
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
index a1e05ee..401a64f7 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
@@ -8,6 +8,7 @@
 
 #include "base/command_line.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats.h"
@@ -98,12 +99,10 @@
           : config_->GetProxiesForHttp();
 
   // Remove the proxies that are unsupported for this request.
-  proxies_for_http.erase(
-      std::remove_if(proxies_for_http.begin(), proxies_for_http.end(),
-                     [content_type](const DataReductionProxyServer& proxy) {
-                       return !proxy.SupportsResourceType(content_type);
-                     }),
-      proxies_for_http.end());
+  base::EraseIf(proxies_for_http,
+                [content_type](const DataReductionProxyServer& proxy) {
+                  return !proxy.SupportsResourceType(content_type);
+                });
 
   base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
       warmup_proxy = config_->GetInFlightWarmupProxyDetails();
@@ -120,14 +119,11 @@
     bool is_core_proxy = warmup_proxy->second;
     // Remove the proxies with properties that do not match the properties of
     // the proxy that is being probed.
-    proxies_for_http.erase(
-        std::remove_if(proxies_for_http.begin(), proxies_for_http.end(),
-                       [is_secure_proxy,
-                        is_core_proxy](const DataReductionProxyServer& proxy) {
-                         return proxy.IsSecureProxy() != is_secure_proxy ||
-                                proxy.IsCoreProxy() != is_core_proxy;
-                       }),
-        proxies_for_http.end());
+    base::EraseIf(proxies_for_http, [is_secure_proxy, is_core_proxy](
+                                        const DataReductionProxyServer& proxy) {
+      return proxy.IsSecureProxy() != is_secure_proxy ||
+             proxy.IsCoreProxy() != is_core_proxy;
+    });
   }
 
   // If the proxy is disabled due to warmup URL fetch failing in the past,
diff --git a/components/dom_distiller/core/task_tracker.cc b/components/dom_distiller/core/task_tracker.cc
index bb3236c..95c8315 100644
--- a/components/dom_distiller/core/task_tracker.cc
+++ b/components/dom_distiller/core/task_tracker.cc
@@ -10,6 +10,7 @@
 #include "base/auto_reset.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/dom_distiller/core/distilled_content_store.h"
 #include "components/dom_distiller/core/proto/distilled_article.pb.h"
@@ -112,7 +113,7 @@
 }
 
 void TaskTracker::RemoveViewer(ViewRequestDelegate* delegate) {
-  viewers_.erase(std::remove(viewers_.begin(), viewers_.end(), delegate));
+  base::Erase(viewers_, delegate);
   if (viewers_.empty()) {
     MaybeCancel();
   }
diff --git a/components/gcm_driver/instance_id/instance_id_impl.cc b/components/gcm_driver/instance_id/instance_id_impl.cc
index 46ba83c..49f8ba7 100644
--- a/components/gcm_driver/instance_id/instance_id_impl.cc
+++ b/components/gcm_driver/instance_id/instance_id_impl.cc
@@ -13,6 +13,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/gcm_driver/gcm_driver.h"
@@ -246,7 +247,7 @@
       &id_);
   std::replace(id_.begin(), id_.end(), '+', '-');
   std::replace(id_.begin(), id_.end(), '/', '_');
-  id_.erase(std::remove(id_.begin(), id_.end(), '='), id_.end());
+  base::Erase(id_, '=');
 
   creation_time_ = base::Time::Now();
 
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.cc
index 294004d..a41894e 100644
--- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.cc
+++ b/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.cc
@@ -6,6 +6,8 @@
 
 #include <algorithm>
 
+#include "base/stl_util.h"
+
 namespace {
 static constexpr int CACHE_SIZE = 5;
 }  // namespace
@@ -76,12 +78,10 @@
   // Check if we've already sent an event with this url to the cache. If so,
   // remove it before adding another one.
   const std::string current_url = current_event_.url;
-  auto itr =
-      std::remove_if(events_.begin(), events_.end(),
-                     [current_url](ContextualSuggestionsDebuggingEvent event) {
-                       return current_url == event.url;
-                     });
-  events_.erase(itr, events_.end());
+  base::EraseIf(events_,
+                [current_url](ContextualSuggestionsDebuggingEvent event) {
+                  return current_url == event.url;
+                });
   events_.push_back(current_event_);
 
   // If the cache is too large, then remove the least recently used.
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
index dba4913..a9c23f4 100644
--- a/components/omnibox/browser/autocomplete_result.cc
+++ b/components/omnibox/browser/autocomplete_result.cc
@@ -12,6 +12,7 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/metrics/field_trial_params.h"
+#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/trace_event/memory_usage_estimator.h"
@@ -435,9 +436,7 @@
   // unlikely, as we normally would expect the search-what-you-typed suggestion
   // as a default match (and that's a non-tail suggestion).
   if (non_tail_default == matches->end()) {
-    matches->erase(
-        std::remove_if(matches->begin(), matches->end(), std::not1(is_tail)),
-        matches->end());
+    base::EraseIf(*matches, std::not1(is_tail));
     return;
   }
   // Determine if there are both tail and non-tail matches, excluding the
@@ -457,8 +456,7 @@
   // remove the highest rated suggestions.
   if (any_tail) {
     if (any_non_tail) {
-      matches->erase(std::remove_if(matches->begin(), matches->end(), is_tail),
-                     matches->end());
+      base::EraseIf(*matches, is_tail);
     } else {
       // We want the non-tail default match to be first. Mark tail suggestions
       // as not a legal default match, so that the default match will be moved
diff --git a/components/omnibox/browser/base_search_provider.cc b/components/omnibox/browser/base_search_provider.cc
index 91ffd7a..a49811a 100644
--- a/components/omnibox/browser/base_search_provider.cc
+++ b/components/omnibox/browser/base_search_provider.cc
@@ -13,6 +13,7 @@
 #include "base/feature_list.h"
 #include "base/i18n/case_conversion.h"
 #include "base/macros.h"
+#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/data_use_measurement/core/data_use_user_data.h"
@@ -506,9 +507,9 @@
 void BaseSearchProvider::OnDeletionComplete(
     bool success, SuggestionDeletionHandler* handler) {
   RecordDeletionResult(success);
-  deletion_handlers_.erase(std::remove_if(
-      deletion_handlers_.begin(), deletion_handlers_.end(),
+  base::EraseIf(
+      deletion_handlers_,
       [handler](const std::unique_ptr<SuggestionDeletionHandler>& elem) {
         return elem.get() == handler;
-      }));
+      });
 }
diff --git a/components/omnibox/browser/shortcuts_provider.cc b/components/omnibox/browser/shortcuts_provider.cc
index e06b594c..36545b69 100644
--- a/components/omnibox/browser/shortcuts_provider.cc
+++ b/components/omnibox/browser/shortcuts_provider.cc
@@ -16,6 +16,7 @@
 #include "base/i18n/case_conversion.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
+#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -144,9 +145,7 @@
   if (backend)  // Can be NULL in Incognito.
     backend->DeleteShortcutsWithURL(url);
 
-  matches_.erase(std::remove_if(matches_.begin(), matches_.end(),
-                                DestinationURLEqualsURL(url)),
-                 matches_.end());
+  base::EraseIf(matches_, DestinationURLEqualsURL(url));
   // NOTE: |match| is now dead!
 
   // Delete the match from the history DB. This will eventually result in a
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc
index 3b192ad..be4b1e2 100644
--- a/components/password_manager/core/browser/password_manager_util_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/macros.h"
+#include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_task_environment.h"
@@ -311,8 +312,7 @@
         // A non-best match form must not be in |best_matches|.
         EXPECT_NE(best_matches[form->username_value], form);
 
-        matches.erase(std::remove(matches.begin(), matches.end(), form),
-                      matches.end());
+        base::Erase(matches, form);
       }
       // Expect that all non-best matches were found in |matches| and only best
       // matches left.
diff --git a/components/password_manager/core/browser/password_reuse_detector.cc b/components/password_manager/core/browser/password_reuse_detector.cc
index 14f08a9..1fbd85d 100644
--- a/components/password_manager/core/browser/password_reuse_detector.cc
+++ b/components/password_manager/core/browser/password_reuse_detector.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <utility>
 
+#include "base/stl_util.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/hash_password_manager.h"
 #include "components/password_manager/core/browser/password_hash_data.h"
@@ -245,13 +246,10 @@
   if (!gaia_password_hash_data_list_)
     return;
 
-  gaia_password_hash_data_list_->erase(
-      std::remove_if(gaia_password_hash_data_list_->begin(),
-                     gaia_password_hash_data_list_->end(),
-                     [&username](const PasswordHashData& data) {
-                       return data.username == username;
-                     }),
-      gaia_password_hash_data_list_->end());
+  base::EraseIf(*gaia_password_hash_data_list_,
+                [&username](const PasswordHashData& data) {
+                  return data.username == username;
+                });
 }
 
 void PasswordReuseDetector::ClearAllGaiaPasswordHash() {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index f6ccbb3..3855898 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -12856,7 +12856,7 @@
       'tags': [],
       'desc': '''Specifies a list of websites that are installed silently, without user interaction, and which cannot be uninstalled nor disabled by the user.
 
-      Each list item of the policy is an object with two members: "url" and "launch_container". "url" should be the URL of the web app to install and "launch_container" should be either "window" or "tab" to indicate how the Web App will be opened once installed. If "launch_container" is ommitted, the app will launch in a window if Chrome considers it a Progressive Web App and in a tab otherwise.''',
+      Each list item of the policy is an object with two members: "url" and "launch_container". "url" should be the URL of the web app to install and "launch_container" should be either "window" or "tab" to indicate how the Web App will be opened once installed. If "launch_container" is omitted, the app will launch in a window if Chrome considers it a Progressive Web App and in a tab otherwise.''',
       'label': '''URLs for Web Apps to be silently installed.''',
     },
   ],
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.cc b/components/safe_browsing/web_ui/safe_browsing_ui.cc
index bd4b51c..4f9b8e1 100644
--- a/components/safe_browsing/web_ui/safe_browsing_ui.cc
+++ b/components/safe_browsing/web_ui/safe_browsing_ui.cc
@@ -17,6 +17,7 @@
 #include "base/json/json_string_value_serializer.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/singleton.h"
+#include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "base/values.h"
@@ -171,9 +172,7 @@
 }
 
 void WebUIInfoSingleton::UnregisterWebUIInstance(SafeBrowsingUIHandler* webui) {
-  webui_instances_.erase(
-      std::remove(webui_instances_.begin(), webui_instances_.end(), webui),
-      webui_instances_.end());
+  base::Erase(webui_instances_, webui);
   if (webui_instances_.empty()) {
     ClearCSBRRsSent();
     ClearClientDownloadRequestsSent();
diff --git a/components/signin/core/browser/account_fetcher_service.cc b/components/signin/core/browser/account_fetcher_service.cc
index e830cb0f..889e0f6 100644
--- a/components/signin/core/browser/account_fetcher_service.cc
+++ b/components/signin/core/browser/account_fetcher_service.cc
@@ -64,7 +64,8 @@
 // static
 void AccountFetcherService::RegisterPrefs(
     user_prefs::PrefRegistrySyncable* user_prefs) {
-  user_prefs->RegisterInt64Pref(kLastUpdatePref, 0);
+  user_prefs->RegisterTimePref(AccountFetcherService::kLastUpdatePref,
+                               base::Time());
 }
 
 void AccountFetcherService::Initialize(
@@ -85,9 +86,8 @@
   DCHECK(image_decoder);
   DCHECK(!image_decoder_);
   image_decoder_ = std::move(image_decoder);
-
-  last_updated_ = base::Time::FromInternalValue(
-      signin_client_->GetPrefs()->GetInt64(kLastUpdatePref));
+  last_updated_ = signin_client_->GetPrefs()->GetTime(
+      AccountFetcherService::kLastUpdatePref);
 }
 
 void AccountFetcherService::Shutdown() {
@@ -176,8 +176,8 @@
   DCHECK(network_fetches_enabled_);
   RefreshAllAccountInfo(false);
   last_updated_ = base::Time::Now();
-  signin_client_->GetPrefs()->SetInt64(kLastUpdatePref,
-                                       last_updated_.ToInternalValue());
+  signin_client_->GetPrefs()->SetTime(AccountFetcherService::kLastUpdatePref,
+                                      last_updated_);
   ScheduleNextRefresh();
 }
 
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc
index 8dff746d..32bb8216 100644
--- a/components/signin/core/browser/account_reconcilor.cc
+++ b/components/signin/core/browser/account_reconcilor.cc
@@ -449,9 +449,7 @@
     }
   }
 
-  chrome_accounts.erase(std::remove(chrome_accounts.begin(),
-                                    chrome_accounts.end(), std::string()),
-                        chrome_accounts.end());
+  base::Erase(chrome_accounts, std::string());
 
   VLOG(1) << "AccountReconcilor::ValidateAccountsFromTokenService: "
           << "Chrome " << chrome_accounts.size() << " accounts";
diff --git a/components/signin/core/browser/account_tracker_service.cc b/components/signin/core/browser/account_tracker_service.cc
index fe4451e..2076c35c 100644
--- a/components/signin/core/browser/account_tracker_service.cc
+++ b/components/signin/core/browser/account_tracker_service.cc
@@ -323,7 +323,7 @@
 }
 
 void AccountTrackerService::SetIsChildAccount(const std::string& account_id,
-                                              const bool& is_child_account) {
+                                              bool is_child_account) {
   DCHECK(base::ContainsKey(accounts_, account_id));
   AccountState& state = accounts_[account_id];
   if (state.info.is_child_account == is_child_account)
@@ -336,7 +336,7 @@
 
 void AccountTrackerService::SetIsAdvancedProtectionAccount(
     const std::string& account_id,
-    const bool& is_under_advanced_protection) {
+    bool is_under_advanced_protection) {
   DCHECK(base::ContainsKey(accounts_, account_id));
   AccountState& state = accounts_[account_id];
   if (state.info.is_under_advanced_protection == is_under_advanced_protection)
diff --git a/components/signin/core/browser/account_tracker_service.h b/components/signin/core/browser/account_tracker_service.h
index 739583dda..9a787b1 100644
--- a/components/signin/core/browser/account_tracker_service.h
+++ b/components/signin/core/browser/account_tracker_service.h
@@ -124,12 +124,11 @@
   std::string SeedAccountInfo(AccountInfo info);
 
   // Sets whether the account is a Unicorn account.
-  void SetIsChildAccount(const std::string& account_id,
-                         const bool& is_child_account);
+  void SetIsChildAccount(const std::string& account_id, bool is_child_account);
 
   // Sets whether the account is under advanced protection.
   void SetIsAdvancedProtectionAccount(const std::string& account_id,
-                                      const bool& is_under_advanced_protection);
+                                      bool is_under_advanced_protection);
 
   void RemoveAccount(const std::string& account_id);
 
diff --git a/components/signin/core/browser/account_tracker_service_unittest.cc b/components/signin/core/browser/account_tracker_service_unittest.cc
index fd4bc591..b5ee989 100644
--- a/components/signin/core/browser/account_tracker_service_unittest.cc
+++ b/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -290,8 +290,8 @@
     pref_service_.registry()->RegisterIntegerPref(
         prefs::kAccountIdMigrationState,
         AccountTrackerService::MIGRATION_NOT_STARTED);
-    pref_service_.registry()->RegisterInt64Pref(
-        AccountFetcherService::kLastUpdatePref, 0);
+    pref_service_.registry()->RegisterTimePref(
+        AccountFetcherService::kLastUpdatePref, base::Time());
     signin_client_.reset(new TestSigninClient(&pref_service_));
 
     account_tracker_.reset(new AccountTrackerService());
@@ -893,9 +893,8 @@
   // Rewind the time by half a day, which shouldn't be enough to trigger a
   // network refresh.
   base::Time fake_update = base::Time::Now() - base::TimeDelta::FromHours(12);
-  signin_client()->GetPrefs()->SetInt64(
-      AccountFetcherService::kLastUpdatePref,
-      fake_update.ToInternalValue());
+  signin_client()->GetPrefs()->SetTime(AccountFetcherService::kLastUpdatePref,
+                                       fake_update);
 
   // Instantiate a new ATS, making sure the persisted accounts are still there
   // and that no network fetches happen.
@@ -920,9 +919,8 @@
 
   // Rewind the last updated time enough to trigger a network refresh.
   fake_update = base::Time::Now() - base::TimeDelta::FromHours(25);
-  signin_client()->GetPrefs()->SetInt64(
-      AccountFetcherService::kLastUpdatePref,
-      fake_update.ToInternalValue());
+  signin_client()->GetPrefs()->SetTime(AccountFetcherService::kLastUpdatePref,
+                                       fake_update);
 
   // Instantiate a new tracker and validate that even though the AccountInfos
   // are still valid, the network fetches are started.
diff --git a/components/signin/core/browser/fake_account_fetcher_service.cc b/components/signin/core/browser/fake_account_fetcher_service.cc
index bf1b459..684cb9e 100644
--- a/components/signin/core/browser/fake_account_fetcher_service.cc
+++ b/components/signin/core/browser/fake_account_fetcher_service.cc
@@ -34,7 +34,7 @@
 
 void FakeAccountFetcherService::FakeSetIsChildAccount(
     const std::string& account_id,
-    const bool& is_child_account) {
+    bool is_child_account) {
   SetIsChildAccount(account_id, is_child_account);
 }
 
diff --git a/components/signin/core/browser/fake_account_fetcher_service.h b/components/signin/core/browser/fake_account_fetcher_service.h
index f9d8d158..5a3cafa2 100644
--- a/components/signin/core/browser/fake_account_fetcher_service.h
+++ b/components/signin/core/browser/fake_account_fetcher_service.h
@@ -34,7 +34,7 @@
                                 const std::string& locale,
                                 const std::string& picture_url);
   void FakeSetIsChildAccount(const std::string& account_id,
-                             const bool& is_child_account);
+                             bool is_child_account);
 
   FakeAccountFetcherService();
 
diff --git a/components/subresource_filter/core/common/perftests/data/UnindexedRules_7.54 b/components/subresource_filter/core/common/perftests/data/UnindexedRules_7.54
deleted file mode 100644
index 950626d..0000000
--- a/components/subresource_filter/core/common/perftests/data/UnindexedRules_7.54
+++ /dev/null
Binary files differ
diff --git a/components/subresource_filter/core/common/perftests/data/UnindexedRules_8.0 b/components/subresource_filter/core/common/perftests/data/UnindexedRules_8.0
new file mode 100644
index 0000000..36b59577
--- /dev/null
+++ b/components/subresource_filter/core/common/perftests/data/UnindexedRules_8.0
Binary files differ
diff --git a/components/subresource_filter/core/common/perftests/indexed_ruleset_perftest.cc b/components/subresource_filter/core/common/perftests/indexed_ruleset_perftest.cc
index 92f2848..10c118b 100644
--- a/components/subresource_filter/core/common/perftests/indexed_ruleset_perftest.cc
+++ b/components/subresource_filter/core/common/perftests/indexed_ruleset_perftest.cc
@@ -46,7 +46,7 @@
 
     unindexed_path_ = dir_path.AppendASCII(
         "components/subresource_filter/core/common/perftests/"
-        "data/UnindexedRules_7.54");
+        "data/UnindexedRules_8.0");
 
     ASSERT_TRUE(scoped_dir_.CreateUniqueTempDir());
     base::FilePath indexed_path =
diff --git a/components/subresource_filter/tools/BUILD.gn b/components/subresource_filter/tools/BUILD.gn
index 10e22ea..172441c 100644
--- a/components/subresource_filter/tools/BUILD.gn
+++ b/components/subresource_filter/tools/BUILD.gn
@@ -100,7 +100,7 @@
     ]
 
     inputs = [
-      "//components/subresource_filter/core/common/perftests/data/UnindexedRules_7.54",
+      "//components/subresource_filter/core/common/perftests/data/UnindexedRules_8.0",
     ]
     deps = [
       ":subresource_indexing_tool",
diff --git a/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc b/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc
index 66c8c43..e1050156 100644
--- a/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc
+++ b/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "components/subresource_filter/tools/rule_parser/rule_parser.h"
@@ -277,13 +278,11 @@
   input.reset();
   output.reset();
 
-  contents.url_rules.erase(
-      std::remove_if(contents.url_rules.begin(), contents.url_rules.end(),
-                     [](const url_pattern_index::proto::UrlRule& rule) {
-                       return rule.url_pattern_type() ==
-                              url_pattern_index::proto::URL_PATTERN_TYPE_REGEXP;
-                     }),
-      contents.url_rules.end());
+  base::EraseIf(contents.url_rules,
+                [](const url_pattern_index::proto::UrlRule& rule) {
+                  return rule.url_pattern_type() ==
+                         url_pattern_index::proto::URL_PATTERN_TYPE_REGEXP;
+                });
   contents.css_rules.clear();
   EXPECT_EQ(target_ruleset.ReadContents(), contents);
 }
diff --git a/components/sync_bookmarks/synced_bookmark_tracker.cc b/components/sync_bookmarks/synced_bookmark_tracker.cc
index 316997b2..a0ffecd 100644
--- a/components/sync_bookmarks/synced_bookmark_tracker.cc
+++ b/components/sync_bookmarks/synced_bookmark_tracker.cc
@@ -9,6 +9,7 @@
 
 #include "base/base64.h"
 #include "base/sha1.h"
+#include "base/stl_util.h"
 #include "components/bookmarks/browser/bookmark_node.h"
 #include "components/sync/base/time.h"
 #include "components/sync/base/unique_position.h"
@@ -169,10 +170,7 @@
   const Entity* entity = GetEntityForSyncId(sync_id);
   DCHECK(entity);
   bookmark_node_to_entities_map_.erase(entity->bookmark_node());
-  ordered_local_tombstones_.erase(
-      std::remove(ordered_local_tombstones_.begin(),
-                  ordered_local_tombstones_.end(), entity),
-      ordered_local_tombstones_.end());
+  base::Erase(ordered_local_tombstones_, entity);
   sync_id_to_entities_map_.erase(sync_id);
 }
 
diff --git a/components/translate/core/browser/resources/translate.js b/components/translate/core/browser/resources/translate.js
index 1c9e60d..5b5ce6b4 100644
--- a/components/translate/core/browser/resources/translate.js
+++ b/components/translate/core/browser/resources/translate.js
@@ -114,16 +114,6 @@
    */
   var resultCallback;
 
-  /**
-   * Listens to security policy violations to set |errorCode|.
-   */
-  document.addEventListener('securitypolicyviolation', function(event) {
-    if (securityOrigin.startsWith(event.blockedURI)) {
-      errorCode = ERROR['BAD_ORIGIN'];
-      invokeReadyCallback();
-    }
-  });
-
   function checkLibReady() {
     if (lib.isAvailable()) {
       readyTime = performance.now();
diff --git a/components/translate/core/language_detection/chinese_script_classifier.cc b/components/translate/core/language_detection/chinese_script_classifier.cc
index c34d0e6f..612cc16e 100644
--- a/components/translate/core/language_detection/chinese_script_classifier.cc
+++ b/components/translate/core/language_detection/chinese_script_classifier.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "third_party/icu/source/common/unicode/uniset.h"
 #include "third_party/icu/source/common/unicode/unistr.h"
@@ -782,9 +783,7 @@
   base::TruncateUTF8ToByteSize(input, 500, &input_subset);
 
   // Remove whitespace since transliterators may not preserve it.
-  input_subset.erase(std::remove_if(input_subset.begin(), input_subset.end(),
-                                    base::IsUnicodeWhitespace),
-                     input_subset.end());
+  base::EraseIf(input_subset, base::IsUnicodeWhitespace);
 
   // Convert the input to icu::UnicodeString so we can iterate over codepoints.
   icu::UnicodeString input_codepoints =
diff --git a/components/translate/ios/browser/ios_translate_driver.h b/components/translate/ios/browser/ios_translate_driver.h
index 8c6f255..4ef97966 100644
--- a/components/translate/ios/browser/ios_translate_driver.h
+++ b/components/translate/ios/browser/ios_translate_driver.h
@@ -12,7 +12,6 @@
 #include "base/memory/weak_ptr.h"
 #include "components/language/ios/browser/ios_language_detection_tab_helper.h"
 #include "components/translate/core/browser/translate_driver.h"
-#include "components/translate/core/common/translate_errors.h"
 #include "components/translate/ios/browser/language_detection_controller.h"
 #include "components/translate/ios/browser/translate_controller.h"
 #include "ios/web/public/web_state/web_state_observer.h"
@@ -87,10 +86,10 @@
   void OnLanguageDetermined(const LanguageDetectionDetails& details);
 
   // TranslateController::Observer methods.
-  void OnTranslateScriptReady(TranslateErrors::Type error_type,
+  void OnTranslateScriptReady(bool success,
                               double load_time,
                               double ready_time) override;
-  void OnTranslateComplete(TranslateErrors::Type error_type,
+  void OnTranslateComplete(bool success,
                            const std::string& original_language,
                            double translation_time) override;
 
diff --git a/components/translate/ios/browser/ios_translate_driver.mm b/components/translate/ios/browser/ios_translate_driver.mm
index 8d945b7..87409a6 100644
--- a/components/translate/ios/browser/ios_translate_driver.mm
+++ b/components/translate/ios/browser/ios_translate_driver.mm
@@ -13,6 +13,7 @@
 #include "components/translate/core/browser/translate_manager.h"
 #include "components/translate/core/common/language_detection_details.h"
 #include "components/translate/core/common/translate_constants.h"
+#include "components/translate/core/common/translate_errors.h"
 #include "components/translate/core/common/translate_metrics.h"
 #import "components/translate/ios/browser/js_language_detection_manager.h"
 #import "components/translate/ios/browser/js_translate_manager.h"
@@ -226,16 +227,15 @@
 
 // TranslateController::Observer implementation.
 
-void IOSTranslateDriver::OnTranslateScriptReady(
-    TranslateErrors::Type error_type,
-    double load_time,
-    double ready_time) {
+void IOSTranslateDriver::OnTranslateScriptReady(bool success,
+                                                double load_time,
+                                                double ready_time) {
   if (!IsPageValid(pending_page_seq_no_))
     return;
 
-  if (error_type != TranslateErrors::NONE) {
+  if (!success) {
     translate_manager_->PageTranslated(source_language_, target_language_,
-                                       error_type);
+                                       TranslateErrors::INITIALIZATION_ERROR);
     return;
   }
 
@@ -249,15 +249,16 @@
 }
 
 void IOSTranslateDriver::OnTranslateComplete(
-    TranslateErrors::Type error_type,
+    bool success,
     const std::string& original_language,
     double translation_time) {
   if (!IsPageValid(pending_page_seq_no_))
     return;
 
-  if (error_type != TranslateErrors::NONE) {
+  if (!success) {
+    // TODO(toyoshim): Check |errorCode| of translate.js and notify it here.
     translate_manager_->PageTranslated(source_language_, target_language_,
-                                       error_type);
+                                       TranslateErrors::TRANSLATION_ERROR);
   }
 
   TranslationDidSucceed(source_language_, target_language_,
diff --git a/components/translate/ios/browser/resources/translate_ios.js b/components/translate/ios/browser/resources/translate_ios.js
index c2e95a3c..3f43a0a 100644
--- a/components/translate/ios/browser/resources/translate_ios.js
+++ b/components/translate/ios/browser/resources/translate_ios.js
@@ -16,7 +16,7 @@
 cr.googleTranslate.readyCallback = function() {
   __gCrWeb.message.invokeOnHost({
       'command': 'translate.ready',
-      'errorCode': cr.googleTranslate.errorCode,
+      'timeout': cr.googleTranslate.error,
       'loadTime': cr.googleTranslate.loadTime,
       'readyTime': cr.googleTranslate.readyTime});
 }
@@ -27,7 +27,7 @@
 cr.googleTranslate.resultCallback = function() {
   __gCrWeb.message.invokeOnHost({
       'command': 'translate.status',
-      'errorCode': cr.googleTranslate.errorCode,
+      'success': !cr.googleTranslate.error,
       'originalPageLanguage': cr.googleTranslate.sourceLang,
       'translationTime': cr.googleTranslate.translationTime});
 }
diff --git a/components/translate/ios/browser/translate_controller.h b/components/translate/ios/browser/translate_controller.h
index 34333de..1b91fef 100644
--- a/components/translate/ios/browser/translate_controller.h
+++ b/components/translate/ios/browser/translate_controller.h
@@ -11,7 +11,6 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "components/translate/core/common/translate_errors.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 
 @class JsTranslateManager;
@@ -35,14 +34,13 @@
   class Observer {
    public:
     // Called when the translate script is ready.
-    // |error_type| Indicates error code.
-    virtual void OnTranslateScriptReady(TranslateErrors::Type error_type,
+    // In case of timeout, |success| is false.
+    virtual void OnTranslateScriptReady(bool success,
                                         double load_time,
                                         double ready_time) = 0;
 
     // Called when the translation is complete.
-    // |error_type| Indicates error code.
-    virtual void OnTranslateComplete(TranslateErrors::Type error_type,
+    virtual void OnTranslateComplete(bool success,
                                      const std::string& original_language,
                                      double translation_time) = 0;
   };
diff --git a/components/translate/ios/browser/translate_controller.mm b/components/translate/ios/browser/translate_controller.mm
index bdfe588e..b125f48 100644
--- a/components/translate/ios/browser/translate_controller.mm
+++ b/components/translate/ios/browser/translate_controller.mm
@@ -94,21 +94,17 @@
 
 bool TranslateController::OnTranslateReady(
     const base::DictionaryValue& command) {
-  double error_code = 0.;
-  double load_time = 0.;
-  double ready_time = 0.;
-
-  if (!command.HasKey("errorCode") ||
-      !command.GetDouble("errorCode", &error_code) ||
-      error_code < TranslateErrors::NONE ||
-      error_code >= TranslateErrors::TRANSLATE_ERROR_MAX) {
+  if (!command.HasKey("timeout")) {
     NOTREACHED();
     return false;
   }
 
-  TranslateErrors::Type error_type =
-      static_cast<TranslateErrors::Type>(error_code);
-  if (error_type == TranslateErrors::NONE) {
+  bool timeout = false;
+  double load_time = 0.;
+  double ready_time = 0.;
+
+  command.GetBoolean("timeout", &timeout);
+  if (!timeout) {
     if (!command.HasKey("loadTime") || !command.HasKey("readyTime")) {
       NOTREACHED();
       return false;
@@ -117,27 +113,23 @@
     command.GetDouble("readyTime", &ready_time);
   }
   if (observer_)
-    observer_->OnTranslateScriptReady(error_type, load_time, ready_time);
+    observer_->OnTranslateScriptReady(!timeout, load_time, ready_time);
   return true;
 }
 
 bool TranslateController::OnTranslateComplete(
     const base::DictionaryValue& command) {
-  double error_code = 0.;
-  std::string original_language;
-  double translation_time = 0.;
-
-  if (!command.HasKey("errorCode") ||
-      !command.GetDouble("errorCode", &error_code) ||
-      error_code < TranslateErrors::NONE ||
-      error_code >= TranslateErrors::TRANSLATE_ERROR_MAX) {
+  if (!command.HasKey("success")) {
     NOTREACHED();
     return false;
   }
 
-  TranslateErrors::Type error_type =
-      static_cast<TranslateErrors::Type>(error_code);
-  if (error_type == TranslateErrors::NONE) {
+  bool success = false;
+  std::string original_language;
+  double translation_time = 0.;
+
+  command.GetBoolean("success", &success);
+  if (success) {
     if (!command.HasKey("originalPageLanguage") ||
         !command.HasKey("translationTime")) {
       NOTREACHED();
@@ -148,7 +140,7 @@
   }
 
   if (observer_)
-    observer_->OnTranslateComplete(error_type, original_language,
+    observer_->OnTranslateComplete(success, original_language,
                                    translation_time);
   return true;
 }
diff --git a/components/translate/ios/browser/translate_controller_unittest.mm b/components/translate/ios/browser/translate_controller_unittest.mm
index 3ac13231..54234bf 100644
--- a/components/translate/ios/browser/translate_controller_unittest.mm
+++ b/components/translate/ios/browser/translate_controller_unittest.mm
@@ -24,7 +24,7 @@
  protected:
   TranslateControllerTest()
       : test_web_state_(new web::TestWebState),
-        error_type_(TranslateErrors::Type::NONE),
+        success_(false),
         ready_time_(0),
         load_time_(0),
         translation_time_(0),
@@ -38,20 +38,20 @@
   }
 
   // TranslateController::Observer methods.
-  void OnTranslateScriptReady(TranslateErrors::Type error_type,
+  void OnTranslateScriptReady(bool success,
                               double load_time,
                               double ready_time) override {
     on_script_ready_called_ = true;
-    error_type_ = error_type;
+    success_ = success;
     load_time_ = load_time;
     ready_time_ = ready_time;
   }
 
-  void OnTranslateComplete(TranslateErrors::Type error_type,
+  void OnTranslateComplete(bool success,
                            const std::string& original_language,
                            double translation_time) override {
     on_translate_complete_called_ = true;
-    error_type_ = error_type;
+    success_ = success;
     original_language_ = original_language;
     translation_time_ = translation_time;
   }
@@ -59,7 +59,7 @@
   std::unique_ptr<web::TestWebState> test_web_state_;
   id mock_js_translate_manager_;
   std::unique_ptr<TranslateController> translate_controller_;
-  TranslateErrors::Type error_type_;
+  bool success_;
   double ready_time_;
   double load_time_;
   std::string original_language_;
@@ -80,7 +80,7 @@
 TEST_F(TranslateControllerTest, OnIFrameJavascriptCommandReceived) {
   base::DictionaryValue command;
   command.SetString("command", "translate.ready");
-  command.SetDouble("errorCode", TranslateErrors::TRANSLATION_TIMEOUT);
+  command.SetBoolean("timeout", true);
   command.SetDouble("loadTime", .0);
   command.SetDouble("readyTime", .0);
   EXPECT_FALSE(translate_controller_->OnJavascriptCommandReceived(
@@ -93,7 +93,7 @@
 TEST_F(TranslateControllerTest, OnTranslateScriptReadyTimeoutCalled) {
   base::DictionaryValue command;
   command.SetString("command", "translate.ready");
-  command.SetDouble("errorCode", TranslateErrors::TRANSLATION_TIMEOUT);
+  command.SetBoolean("timeout", true);
   command.SetDouble("loadTime", .0);
   command.SetDouble("readyTime", .0);
   EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived(
@@ -101,11 +101,11 @@
       /*is_main_frame=*/true));
   EXPECT_TRUE(on_script_ready_called_);
   EXPECT_FALSE(on_translate_complete_called_);
-  EXPECT_FALSE(error_type_ == TranslateErrors::NONE);
+  EXPECT_FALSE(success_);
 }
 
 // Tests that OnTranslateScriptReady() is called with the right parameters when
-// a |translate.ready| message is received from the JS side.
+// a |translate.ready| message is recieved from the JS side.
 TEST_F(TranslateControllerTest, OnTranslateScriptReadyCalled) {
   // Arbitrary values.
   double some_load_time = 23.1;
@@ -113,7 +113,7 @@
 
   base::DictionaryValue command;
   command.SetString("command", "translate.ready");
-  command.SetDouble("errorCode", TranslateErrors::NONE);
+  command.SetBoolean("timeout", false);
   command.SetDouble("loadTime", some_load_time);
   command.SetDouble("readyTime", some_ready_time);
   EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived(
@@ -121,13 +121,13 @@
       /*is_main_frame=*/true));
   EXPECT_TRUE(on_script_ready_called_);
   EXPECT_FALSE(on_translate_complete_called_);
-  EXPECT_TRUE(error_type_ == TranslateErrors::NONE);
+  EXPECT_TRUE(success_);
   EXPECT_EQ(some_load_time, load_time_);
   EXPECT_EQ(some_ready_time, ready_time_);
 }
 
 // Tests that OnTranslateComplete() is called with the right parameters when a
-// |translate.status| message is received from the JS side.
+// |translate.status| message is recieved from the JS side.
 TEST_F(TranslateControllerTest, TranslationSuccess) {
   // Arbitrary values.
   std::string some_original_language("en");
@@ -135,7 +135,7 @@
 
   base::DictionaryValue command;
   command.SetString("command", "translate.status");
-  command.SetDouble("errorCode", TranslateErrors::NONE);
+  command.SetBoolean("success", true);
   command.SetString("originalPageLanguage", some_original_language);
   command.SetDouble("translationTime", some_translation_time);
   EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived(
@@ -143,23 +143,23 @@
       /*is_main_frame=*/true));
   EXPECT_FALSE(on_script_ready_called_);
   EXPECT_TRUE(on_translate_complete_called_);
-  EXPECT_TRUE(error_type_ == TranslateErrors::NONE);
+  EXPECT_TRUE(success_);
   EXPECT_EQ(some_original_language, original_language_);
   EXPECT_EQ(some_translation_time, translation_time_);
 }
 
 // Tests that OnTranslateComplete() is called with the right parameters when a
-// |translate.status| message is received from the JS side.
+// |translate.status| message is recieved from the JS side.
 TEST_F(TranslateControllerTest, TranslationFailure) {
   base::DictionaryValue command;
   command.SetString("command", "translate.status");
-  command.SetDouble("errorCode", TranslateErrors::INITIALIZATION_ERROR);
+  command.SetBoolean("success", false);
   EXPECT_TRUE(translate_controller_->OnJavascriptCommandReceived(
       command, GURL("http://google.com"), /*interacting*/ false,
       /*is_main_frame=*/true));
   EXPECT_FALSE(on_script_ready_called_);
   EXPECT_TRUE(on_translate_complete_called_);
-  EXPECT_FALSE(error_type_ == TranslateErrors::NONE);
+  EXPECT_FALSE(success_);
 }
 
 }  // namespace translate
diff --git a/components/ukm/content/source_url_recorder.cc b/components/ukm/content/source_url_recorder.cc
index f4a09a1..d734bcf 100644
--- a/components/ukm/content/source_url_recorder.cc
+++ b/components/ukm/content/source_url_recorder.cc
@@ -23,6 +23,11 @@
 
 namespace internal {
 
+int64_t CreateUniqueTabId() {
+  static int64_t unique_id_counter = 0;
+  return ++unique_id_counter;
+}
+
 // SourceUrlRecorderWebContentsObserver is responsible for recording UKM source
 // URLs, for all (any only) main frame navigations in a given WebContents.
 // SourceUrlRecorderWebContentsObserver records both the final URL for a
@@ -38,10 +43,19 @@
   // associated with the WebContents, this method is a no-op.
   static void CreateForWebContents(content::WebContents* web_contents);
 
+  // content::WebContentsObserver:
   void DidStartNavigation(
       content::NavigationHandle* navigation_handle) override;
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
+  void DidOpenRequestedURL(content::WebContents* new_contents,
+                           content::RenderFrameHost* source_render_frame_host,
+                           const GURL& url,
+                           const content::Referrer& referrer,
+                           WindowOpenDisposition disposition,
+                           ui::PageTransition transition,
+                           bool started_from_context_menu,
+                           bool renderer_initiated) override;
 
   ukm::SourceId GetLastCommittedSourceId() const;
 
@@ -83,7 +97,17 @@
   };
   std::vector<PendingEvent> pending_document_created_events_;
 
-  int64_t last_committed_source_id_;
+  SourceId last_committed_source_id_;
+
+  // The source id before |last_committed_source_id_|.
+  SourceId previous_committed_source_id_;
+
+  // The source id of the last committed source in the tab that opened this tab.
+  // Will be set to kInvalidSourceId after the first navigation in this tab is
+  // finished.
+  SourceId opener_source_id_;
+
+  const int64_t tab_id_;
 
   DISALLOW_COPY_AND_ASSIGN(SourceUrlRecorderWebContentsObserver);
 };
@@ -92,7 +116,10 @@
     content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
       bindings_(web_contents, this),
-      last_committed_source_id_(ukm::kInvalidSourceId) {}
+      last_committed_source_id_(ukm::kInvalidSourceId),
+      previous_committed_source_id_(ukm::kInvalidSourceId),
+      opener_source_id_(ukm::kInvalidSourceId),
+      tab_id_(CreateUniqueTabId()) {}
 
 void SourceUrlRecorderWebContentsObserver::DidStartNavigation(
     content::NavigationHandle* navigation_handle) {
@@ -127,6 +154,7 @@
   DCHECK(!navigation_handle->IsSameDocument());
 
   if (navigation_handle->HasCommitted()) {
+    previous_committed_source_id_ = last_committed_source_id_;
     last_committed_source_id_ = ukm::ConvertToSourceId(
         navigation_handle->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID);
   }
@@ -141,6 +169,26 @@
   MaybeRecordUrl(navigation_handle, initial_url);
 
   MaybeFlushPendingEvents();
+
+  // Reset the opener source id. Only the first source in a tab should have an
+  // opener.
+  opener_source_id_ = kInvalidSourceId;
+}
+
+void SourceUrlRecorderWebContentsObserver::DidOpenRequestedURL(
+    content::WebContents* new_contents,
+    content::RenderFrameHost* source_render_frame_host,
+    const GURL& url,
+    const content::Referrer& referrer,
+    WindowOpenDisposition disposition,
+    ui::PageTransition transition,
+    bool started_from_context_menu,
+    bool renderer_initiated) {
+  auto* new_recorder =
+      SourceUrlRecorderWebContentsObserver::FromWebContents(new_contents);
+  if (!new_recorder)
+    return;
+  new_recorder->opener_source_id_ = GetLastCommittedSourceId();
 }
 
 ukm::SourceId SourceUrlRecorderWebContentsObserver::GetLastCommittedSourceId()
@@ -195,13 +243,23 @@
   if (!ukm_recorder)
     return;
 
+  const GURL& final_url = navigation_handle->GetURL();
+
+  UkmSource::NavigationData navigation_data;
+  navigation_data.url = final_url;
+  if (final_url != initial_url)
+    navigation_data.initial_url = initial_url;
+
+  // Careful note: the current navigation may have failed.
+  navigation_data.previous_source_id = navigation_handle->HasCommitted()
+                                           ? previous_committed_source_id_
+                                           : last_committed_source_id_;
+  navigation_data.opener_source_id = opener_source_id_;
+  navigation_data.tab_id = tab_id_;
+
   const ukm::SourceId source_id = ukm::ConvertToSourceId(
       navigation_handle->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID);
-  ukm_recorder->UpdateNavigationURL(source_id, initial_url);
-
-  const GURL& final_url = navigation_handle->GetURL();
-  if (final_url != initial_url)
-    ukm_recorder->UpdateNavigationURL(source_id, final_url);
+  ukm_recorder->RecordNavigation(source_id, navigation_data);
 }
 
 // static
diff --git a/components/ukm/ukm_recorder_impl.cc b/components/ukm/ukm_recorder_impl.cc
index 632e0c3f..24ad0d36 100644
--- a/components/ukm/ukm_recorder_impl.cc
+++ b/components/ukm/ukm_recorder_impl.cc
@@ -139,6 +139,11 @@
   if (url.SchemeIs(url::kAboutScheme) || url.SchemeIs("chrome")) {
     remove_params.ClearQuery();
   }
+  if (url.SchemeIs(kExtensionScheme)) {
+    remove_params.ClearPath();
+    remove_params.ClearQuery();
+    remove_params.ClearRef();
+  }
   return url.ReplaceComponents(remove_params);
 }
 
@@ -391,64 +396,19 @@
 void UkmRecorderImpl::UpdateSourceURL(SourceId source_id,
                                       const GURL& unsanitized_url) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (!recording_enabled_) {
-    RecordDroppedSource(DroppedDataReason::RECORDING_DISABLED);
+  const GURL sanitized_url = SanitizeURL(unsanitized_url);
+  if (!ShouldRecordUrl(source_id, sanitized_url))
     return;
-  }
 
-  if (ShouldRestrictToWhitelistedSourceIds() &&
-      !IsWhitelistedSourceId(source_id)) {
-    RecordDroppedSource(DroppedDataReason::NOT_WHITELISTED);
+  if (base::ContainsKey(recordings_.sources, source_id))
     return;
-  }
-
-  if (unsanitized_url.is_empty()) {
-    RecordDroppedSource(DroppedDataReason::EMPTY_URL);
-    return;
-  }
-
-  recordings_.source_counts.observed++;
-  if (GetSourceIdType(source_id) == SourceIdType::NAVIGATION_ID)
-    recordings_.source_counts.navigation_sources++;
-
-  GURL url = SanitizeURL(unsanitized_url);
-
-  if (!HasSupportedScheme(url)) {
-    RecordDroppedSource(DroppedDataReason::UNSUPPORTED_URL_SCHEME);
-    DVLOG(2) << "Dropped Unsupported UKM URL:" << source_id << ":"
-             << url.spec();
-    return;
-  }
-
-  // Extension URLs need to be specifically enabled and the extension synced.
-  if (url.SchemeIs(kExtensionScheme)) {
-    if (!extensions_enabled_) {
-      RecordDroppedSource(DroppedDataReason::EXTENSION_URLS_DISABLED);
-      return;
-    }
-    if (!is_webstore_extension_callback_ ||
-        !is_webstore_extension_callback_.Run(url.host_piece())) {
-      RecordDroppedSource(DroppedDataReason::EXTENSION_NOT_SYNCED);
-      return;
-    }
-    url = url.GetWithEmptyPath();
-  }
-
-  // Update the pre-existing source if there is any. This happens when the
-  // initial URL is different from the committed URL for the same source, e.g.,
-  // when there is redirection.
-  if (base::ContainsKey(recordings_.sources, source_id)) {
-    recordings_.sources[source_id]->UpdateUrl(url);
-    return;
-  }
 
   if (recordings_.sources.size() >= GetMaxSources()) {
     RecordDroppedSource(DroppedDataReason::MAX_HIT);
     return;
   }
-  recordings_.sources.emplace(source_id,
-                              std::make_unique<UkmSource>(source_id, url));
+  recordings_.sources.emplace(
+      source_id, std::make_unique<UkmSource>(source_id, sanitized_url));
 }
 
 void UkmRecorderImpl::UpdateAppURL(SourceId source_id, const GURL& url) {
@@ -459,6 +419,94 @@
   UpdateSourceURL(source_id, url);
 }
 
+void UkmRecorderImpl::RecordNavigation(
+    SourceId source_id,
+    const UkmSource::NavigationData& unsanitized_navigation_data) {
+  DCHECK(GetSourceIdType(source_id) == SourceIdType::NAVIGATION_ID);
+  // TODO(csharrison): This is a bit messy because it tries not to change
+  // existing behavior from previous code, where if |final_url| should not be
+  // recorded, the entry assumes |initial_url| is the final url. This should be
+  // changed so that the Source isn't even recorded at all if the final URL
+  // should not be recorded.
+  std::vector<GURL> urls;
+  GURL sanitized_initial_url =
+      SanitizeURL(unsanitized_navigation_data.initial_url);
+  GURL sanitized_final_url = SanitizeURL(unsanitized_navigation_data.url);
+  if (!sanitized_initial_url.is_empty() &&
+      ShouldRecordUrl(source_id, sanitized_initial_url)) {
+    urls.push_back(sanitized_initial_url);
+  }
+  if (ShouldRecordUrl(source_id, sanitized_final_url)) {
+    urls.push_back(sanitized_final_url);
+  }
+
+  // Neither URLs passed the ShouldRecordUrl check, so do not create a new
+  // Source for them.
+  if (urls.empty())
+    return;
+
+  UkmSource::NavigationData sanitized_navigation_data =
+      unsanitized_navigation_data.CopyWithSanitizedUrls(urls);
+  DCHECK(!base::ContainsKey(recordings_.sources, source_id));
+  if (recordings_.sources.size() >= GetMaxSources()) {
+    RecordDroppedSource(DroppedDataReason::MAX_HIT);
+    return;
+  }
+  recordings_.sources.emplace(
+      source_id,
+      std::make_unique<UkmSource>(source_id, sanitized_navigation_data));
+}
+
+bool UkmRecorderImpl::ShouldRecordUrl(SourceId source_id,
+                                      const GURL& sanitized_url) {
+  if (!recording_enabled_) {
+    RecordDroppedSource(DroppedDataReason::RECORDING_DISABLED);
+    return false;
+  }
+
+  if (ShouldRestrictToWhitelistedSourceIds() &&
+      !IsWhitelistedSourceId(source_id)) {
+    RecordDroppedSource(DroppedDataReason::NOT_WHITELISTED);
+    return false;
+  }
+
+  if (sanitized_url.is_empty()) {
+    RecordDroppedSource(DroppedDataReason::EMPTY_URL);
+    return false;
+  }
+
+  recordings_.source_counts.observed++;
+
+  // TODO(csharrison): Move this to RecordNavigation. It would be a behavior
+  // change though, since we would only record _once_ per navigation, and we
+  // wouldn't track e.g. unsupported schemes or other cases where we drop after
+  // this point.
+  if (GetSourceIdType(source_id) == SourceIdType::NAVIGATION_ID)
+    recordings_.source_counts.navigation_sources++;
+
+  if (!HasSupportedScheme(sanitized_url)) {
+    RecordDroppedSource(DroppedDataReason::UNSUPPORTED_URL_SCHEME);
+    DVLOG(2) << "Dropped Unsupported UKM URL:" << source_id << ":"
+             << sanitized_url.spec();
+    return false;
+  }
+
+  // Extension URLs need to be specifically enabled and the extension synced.
+  if (sanitized_url.SchemeIs(kExtensionScheme)) {
+    DCHECK_EQ(sanitized_url.GetWithEmptyPath(), sanitized_url);
+    if (!extensions_enabled_) {
+      RecordDroppedSource(DroppedDataReason::EXTENSION_URLS_DISABLED);
+      return false;
+    }
+    if (!is_webstore_extension_callback_ ||
+        !is_webstore_extension_callback_.Run(sanitized_url.host_piece())) {
+      RecordDroppedSource(DroppedDataReason::EXTENSION_NOT_SYNCED);
+      return false;
+    }
+  }
+  return true;
+}
+
 void UkmRecorderImpl::AddEntry(mojom::UkmEntryPtr entry) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
diff --git a/components/ukm/ukm_recorder_impl.h b/components/ukm/ukm_recorder_impl.h
index 028323b..abb2f8a 100644
--- a/components/ukm/ukm_recorder_impl.h
+++ b/components/ukm/ukm_recorder_impl.h
@@ -84,6 +84,9 @@
   // UkmRecorder:
   void UpdateSourceURL(SourceId source_id, const GURL& url) override;
   void UpdateAppURL(SourceId source_id, const GURL& url) override;
+  void RecordNavigation(
+      SourceId source_id,
+      const UkmSource::NavigationData& navigation_data) override;
   using UkmRecorder::RecordOtherURL;
 
   virtual bool ShouldRestrictToWhitelistedSourceIds() const;
@@ -118,6 +121,9 @@
 
   using MetricAggregateMap = std::map<uint64_t, MetricAggregate>;
 
+  // Returns true if |sanitized_url| should be recorded.
+  bool ShouldRecordUrl(SourceId source_id, const GURL& sanitized_url);
+
   void AddEntry(mojom::UkmEntryPtr entry) override;
 
   // Load sampling configurations from field-trial information.
diff --git a/components/ukm/ukm_service_unittest.cc b/components/ukm/ukm_service_unittest.cc
index a2334cf9..83dc43e 100644
--- a/components/ukm/ukm_service_unittest.cc
+++ b/components/ukm/ukm_service_unittest.cc
@@ -61,6 +61,11 @@
     recorder_->UpdateSourceURL(source_id, url);
   }
 
+  void RecordNavigation(SourceId source_id,
+                        const UkmSource::NavigationData& navigation_data) {
+    recorder_->RecordNavigation(source_id, navigation_data);
+  }
+
  private:
   UkmRecorder* recorder_;
 
@@ -253,10 +258,12 @@
   service.EnableRecording(/*extensions=*/false);
   service.EnableReporting();
 
+  UkmSource::NavigationData navigation_data;
+  navigation_data.initial_url = GURL("https://google.com/initial");
+  navigation_data.url = GURL("https://google.com/final");
+
   ukm::SourceId id = GetWhitelistedSourceId(0);
-  recorder.UpdateSourceURL(id, GURL("https://google.com/initial"));
-  recorder.UpdateSourceURL(id, GURL("https://google.com/intermediate"));
-  recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+  recorder.RecordNavigation(id, navigation_data);
 
   service.Flush();
   EXPECT_EQ(GetPersistedLogCount(), 1);
@@ -267,7 +274,7 @@
   const Source& proto_source = proto_report.sources(0);
 
   EXPECT_EQ(id, proto_source.id());
-  EXPECT_EQ(GURL("https://google.com/foobar").spec(), proto_source.url());
+  EXPECT_EQ(GURL("https://google.com/final").spec(), proto_source.url());
   EXPECT_FALSE(proto_source.has_initial_url());
 }
 
@@ -442,9 +449,10 @@
     service.EnableReporting();
 
     ukm::SourceId id = GetWhitelistedSourceId(0);
-    recorder.UpdateSourceURL(id, GURL("https://google.com/initial"));
-    recorder.UpdateSourceURL(id, GURL("https://google.com/intermediate"));
-    recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+    UkmSource::NavigationData navigation_data;
+    navigation_data.initial_url = GURL("https://google.com/initial");
+    navigation_data.url = GURL("https://google.com/final");
+    recorder.RecordNavigation(id, navigation_data);
 
     service.Flush();
     EXPECT_EQ(GetPersistedLogCount(), 1);
@@ -454,7 +462,7 @@
     const Source& proto_source = proto_report.sources(0);
 
     EXPECT_EQ(id, proto_source.id());
-    EXPECT_EQ(GURL("https://google.com/foobar").spec(), proto_source.url());
+    EXPECT_EQ(GURL("https://google.com/final").spec(), proto_source.url());
     EXPECT_EQ(should_record_initial_url, proto_source.has_initial_url());
     if (should_record_initial_url) {
       EXPECT_EQ(GURL("https://google.com/initial").spec(),
diff --git a/components/update_client/utils.cc b/components/update_client/utils.cc
index 8be2a69..131288f 100644
--- a/components/update_client/utils.cc
+++ b/components/update_client/utils.cc
@@ -17,6 +17,7 @@
 #include "base/files/file_util.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/json/json_file_value_serializer.h"
+#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
@@ -190,10 +191,8 @@
 
 void RemoveUnsecureUrls(std::vector<GURL>* urls) {
   DCHECK(urls);
-  urls->erase(std::remove_if(
-                  urls->begin(), urls->end(),
-                  [](const GURL& url) { return !url.SchemeIsCryptographic(); }),
-              urls->end());
+  base::EraseIf(*urls,
+                [](const GURL& url) { return !url.SchemeIsCryptographic(); });
 }
 
 CrxInstaller::Result InstallFunctionWrapper(
diff --git a/components/variations/synthetic_trial_registry.cc b/components/variations/synthetic_trial_registry.cc
index 28e162c..ea07f68 100644
--- a/components/variations/synthetic_trial_registry.cc
+++ b/components/variations/synthetic_trial_registry.cc
@@ -4,6 +4,8 @@
 
 #include "components/variations/synthetic_trial_registry.h"
 
+#include "base/stl_util.h"
+
 namespace variations {
 
 SyntheticTrialRegistry::SyntheticTrialRegistry() = default;
@@ -46,10 +48,7 @@
   auto has_same_trial_name = [trial_name_hash](const SyntheticTrialGroup& x) {
     return x.id.name == trial_name_hash;
   };
-  synthetic_trial_groups_.erase(
-      std::remove_if(synthetic_trial_groups_.begin(),
-                     synthetic_trial_groups_.end(), has_same_trial_name),
-      synthetic_trial_groups_.end());
+  base::EraseIf(synthetic_trial_groups_, has_same_trial_name);
 
   if (group_name_hashes.empty())
     return;
diff --git a/components/zucchini/address_translator.cc b/components/zucchini/address_translator.cc
index 79e7ba6c..5b388da 100644
--- a/components/zucchini/address_translator.cc
+++ b/components/zucchini/address_translator.cc
@@ -7,6 +7,8 @@
 #include <algorithm>
 #include <utility>
 
+#include "base/stl_util.h"
+
 namespace zucchini {
 
 /******** AddressTranslator::OffsetToRvaCache ********/
@@ -77,9 +79,7 @@
   }
 
   // Remove all empty units.
-  units.erase(std::remove_if(units.begin(), units.end(),
-                             [](const Unit& unit) { return unit.IsEmpty(); }),
-              units.end());
+  base::EraseIf(units, [](const Unit& unit) { return unit.IsEmpty(); });
 
   // Sort |units| by RVA, then uniquefy.
   std::sort(units.begin(), units.end(), [](const Unit& a, const Unit& b) {
diff --git a/components/zucchini/ensemble_matcher.cc b/components/zucchini/ensemble_matcher.cc
index 37a7af9..42079d6 100644
--- a/components/zucchini/ensemble_matcher.cc
+++ b/components/zucchini/ensemble_matcher.cc
@@ -8,6 +8,7 @@
 #include <limits>
 
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 
 namespace zucchini {
@@ -30,9 +31,7 @@
   auto num_dex = std::count_if(matches_.begin(), matches_.end(), is_match_dex);
   if (num_dex > 1) {
     LOG(WARNING) << "Found " << num_dex << " DEX: Ignoring all.";
-    matches_.erase(
-        std::remove_if(matches_.begin(), matches_.end(), is_match_dex),
-        matches_.end());
+    base::EraseIf(matches_, is_match_dex);
   }
 }
 
diff --git a/components/zucchini/equivalence_map.cc b/components/zucchini/equivalence_map.cc
index b85fe9f..0711bfb 100644
--- a/components/zucchini/equivalence_map.cc
+++ b/components/zucchini/equivalence_map.cc
@@ -9,6 +9,7 @@
 
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
+#include "base/stl_util.h"
 #include "components/zucchini/encoded_view.h"
 #include "components/zucchini/patch_reader.h"
 #include "components/zucchini/suffix_array.h"
@@ -304,8 +305,7 @@
       src = kInvalidOffset;
     }
   }
-  offsets->erase(std::remove(offsets->begin(), offsets->end(), kInvalidOffset),
-                 offsets->end());
+  base::Erase(*offsets, kInvalidOffset);
   offsets->shrink_to_fit();
 }
 
@@ -365,11 +365,9 @@
   }
 
   // Discard all equivalences with length == 0.
-  equivalences->erase(std::remove_if(equivalences->begin(), equivalences->end(),
-                                     [](const Equivalence& equivalence) {
-                                       return equivalence.length == 0;
-                                     }),
-                      equivalences->end());
+  base::EraseIf(*equivalences, [](const Equivalence& equivalence) {
+    return equivalence.length == 0;
+  });
 }
 
 /******** EquivalenceMap ********/
@@ -541,12 +539,10 @@
   }
 
   // Discard all candidates with similarity smaller than |min_similarity|.
-  candidates_.erase(
-      std::remove_if(candidates_.begin(), candidates_.end(),
-                     [min_similarity](const EquivalenceCandidate& candidate) {
-                       return candidate.similarity < min_similarity;
-                     }),
-      candidates_.end());
+  base::EraseIf(candidates_,
+                [min_similarity](const EquivalenceCandidate& candidate) {
+                  return candidate.similarity < min_similarity;
+                });
 }
 
 }  // namespace zucchini
diff --git a/content/browser/media/audio_output_stream_broker.cc b/content/browser/media/audio_output_stream_broker.cc
index 0d2f3dea..1ddd0ad9 100644
--- a/content/browser/media/audio_output_stream_broker.cc
+++ b/content/browser/media/audio_output_stream_broker.cc
@@ -23,12 +23,14 @@
     const std::string& output_device_id,
     const media::AudioParameters& params,
     const base::UnguessableToken& group_id,
+    const base::Optional<base::UnguessableToken>& processing_id,
     DeleterCallback deleter,
     media::mojom::AudioOutputStreamProviderClientPtr client)
     : AudioStreamBroker(render_process_id, render_frame_id),
       output_device_id_(output_device_id),
       params_(params),
       group_id_(group_id),
+      processing_id_(processing_id),
       deleter_(std::move(deleter)),
       client_(std::move(client)),
       observer_(render_process_id, render_frame_id, stream_id),
@@ -94,7 +96,7 @@
       MediaInternals::GetInstance()->CreateMojoAudioLog(
           media::AudioLogFactory::AudioComponent::AUDIO_OUTPUT_CONTROLLER,
           log_component_id, render_process_id(), render_frame_id()),
-      output_device_id_, params_, group_id_,
+      output_device_id_, params_, group_id_, processing_id_,
       base::BindOnce(&AudioOutputStreamBroker::StreamCreated,
                      weak_ptr_factory_.GetWeakPtr(), std::move(stream)));
 }
diff --git a/content/browser/media/audio_output_stream_broker.h b/content/browser/media/audio_output_stream_broker.h
index f2480aa0..0f04408 100644
--- a/content/browser/media/audio_output_stream_broker.h
+++ b/content/browser/media/audio_output_stream_broker.h
@@ -34,6 +34,7 @@
       const std::string& output_device_id,
       const media::AudioParameters& params,
       const base::UnguessableToken& group_id,
+      const base::Optional<base::UnguessableToken>& processing_id,
       DeleterCallback deleter,
       media::mojom::AudioOutputStreamProviderClientPtr client);
 
@@ -54,6 +55,7 @@
   const std::string output_device_id_;
   const media::AudioParameters params_;
   const base::UnguessableToken group_id_;
+  const base::Optional<base::UnguessableToken> processing_id_;
 
   // Indicates that CreateStream has been called, but not StreamCreated.
   bool awaiting_created_ = false;
diff --git a/content/browser/media/audio_output_stream_broker_unittest.cc b/content/browser/media/audio_output_stream_broker_unittest.cc
index 7a9d488..0d5ea4b4 100644
--- a/content/browser/media/audio_output_stream_broker_unittest.cc
+++ b/content/browser/media/audio_output_stream_broker_unittest.cc
@@ -115,6 +115,7 @@
       const std::string& output_device_id,
       const media::AudioParameters& params,
       const base::UnguessableToken& group_id,
+      const base::Optional<base::UnguessableToken>& processing_id,
       CreateOutputStreamCallback created_callback) final {
     // No way to cleanly exit the test here in case of failure, so use CHECK.
     CHECK(stream_request_data_);
@@ -143,6 +144,7 @@
             kDeviceId,
             TestParams(),
             group,
+            base::nullopt,
             deleter.Get(),
             provider_client.MakePtr())) {}
 
@@ -164,10 +166,10 @@
   MockDeleterCallback deleter;
   StrictMock<MockAudioOutputStreamProviderClient> provider_client;
 
-  AudioOutputStreamBroker broker(kRenderProcessId, kRenderFrameId, kStreamId,
-                                 kDeviceId, TestParams(),
-                                 base::UnguessableToken::Create(),
-                                 deleter.Get(), provider_client.MakePtr());
+  AudioOutputStreamBroker broker(
+      kRenderProcessId, kRenderFrameId, kStreamId, kDeviceId, TestParams(),
+      base::UnguessableToken::Create(), base::nullopt, deleter.Get(),
+      provider_client.MakePtr());
 
   EXPECT_EQ(kRenderProcessId, broker.render_process_id());
   EXPECT_EQ(kRenderFrameId, broker.render_frame_id());
diff --git a/content/browser/media/audio_stream_broker.cc b/content/browser/media/audio_stream_broker.cc
index 6ff668c..09af165 100644
--- a/content/browser/media/audio_stream_broker.cc
+++ b/content/browser/media/audio_stream_broker.cc
@@ -58,11 +58,12 @@
       const std::string& output_device_id,
       const media::AudioParameters& params,
       const base::UnguessableToken& group_id,
+      const base::Optional<base::UnguessableToken>& processing_id,
       AudioStreamBroker::DeleterCallback deleter,
       media::mojom::AudioOutputStreamProviderClientPtr client) final {
     return std::make_unique<AudioOutputStreamBroker>(
         render_process_id, render_frame_id, stream_id, output_device_id, params,
-        group_id, std::move(deleter), std::move(client));
+        group_id, processing_id, std::move(deleter), std::move(client));
   }
 };
 
diff --git a/content/browser/media/audio_stream_broker.h b/content/browser/media/audio_stream_broker.h
index 40af0ea..d630b4ac 100644
--- a/content/browser/media/audio_stream_broker.h
+++ b/content/browser/media/audio_stream_broker.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 #include <string>
+#include <utility>
 
 #include "base/callback.h"
 #include "base/macros.h"
@@ -125,6 +126,7 @@
       const std::string& output_device_id,
       const media::AudioParameters& params,
       const base::UnguessableToken& group_id,
+      const base::Optional<base::UnguessableToken>& processing_id,
       AudioStreamBroker::DeleterCallback deleter,
       media::mojom::AudioOutputStreamProviderClientPtr client) = 0;
 
diff --git a/content/browser/media/forwarding_audio_stream_factory.cc b/content/browser/media/forwarding_audio_stream_factory.cc
index 9ff4814..c00d606 100644
--- a/content/browser/media/forwarding_audio_stream_factory.cc
+++ b/content/browser/media/forwarding_audio_stream_factory.cc
@@ -123,6 +123,7 @@
     RenderFrameHost* frame,
     const std::string& device_id,
     const media::AudioParameters& params,
+    const base::Optional<base::UnguessableToken>& processing_id,
     media::mojom::AudioOutputStreamProviderClientPtr client) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
@@ -132,7 +133,7 @@
   outputs_
       .insert(broker_factory_->CreateAudioOutputStreamBroker(
           process_id, frame_id, ++stream_id_counter_, device_id, params,
-          group_id_,
+          group_id_, processing_id,
           base::BindOnce(&ForwardingAudioStreamFactory::RemoveOutput,
                          base::Unretained(this)),
           std::move(client)))
diff --git a/content/browser/media/forwarding_audio_stream_factory.h b/content/browser/media/forwarding_audio_stream_factory.h
index 3c69b88e..4ad2af2 100644
--- a/content/browser/media/forwarding_audio_stream_factory.h
+++ b/content/browser/media/forwarding_audio_stream_factory.h
@@ -74,6 +74,7 @@
       RenderFrameHost* frame,
       const std::string& device_id,
       const media::AudioParameters& params,
+      const base::Optional<base::UnguessableToken>& processing_id,
       media::mojom::AudioOutputStreamProviderClientPtr client);
 
   void CreateLoopbackStream(
diff --git a/content/browser/media/forwarding_audio_stream_factory_unittest.cc b/content/browser/media/forwarding_audio_stream_factory_unittest.cc
index e076494..b0a5de14 100644
--- a/content/browser/media/forwarding_audio_stream_factory_unittest.cc
+++ b/content/browser/media/forwarding_audio_stream_factory_unittest.cc
@@ -131,6 +131,7 @@
       const std::string& output_device_id,
       const media::AudioParameters& params,
       const base::UnguessableToken& group_id,
+      const base::Optional<base::UnguessableToken>& processing_id,
       AudioStreamBroker::DeleterCallback deleter,
       media::mojom::AudioOutputStreamProviderClientPtr client) final {
     std::unique_ptr<MockBroker> prepared_broker =
@@ -288,7 +289,7 @@
   EXPECT_CALL(*broker, CreateStream(NotNull()));
   mojo::MakeRequest(&client);
   factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                             std::move(client));
+                             base::nullopt, std::move(client));
 }
 
 TEST_F(ForwardingAudioStreamFactoryTest,
@@ -375,14 +376,14 @@
     EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull()));
     mojo::MakeRequest(&client);
     factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                               std::move(client));
+                               base::nullopt, std::move(client));
     testing::Mock::VerifyAndClear(&*main_rfh_broker);
   }
   {
     EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull()));
     mojo::MakeRequest(&client);
     factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams,
-                               std::move(client));
+                               base::nullopt, std::move(client));
     testing::Mock::VerifyAndClear(&*other_rfh_broker);
   }
 
@@ -453,14 +454,14 @@
     EXPECT_CALL(*main_rfh_output_broker, CreateStream(NotNull()));
     mojo::MakeRequest(&output_client);
     factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                               std::move(output_client));
+                               base::nullopt, std::move(output_client));
     testing::Mock::VerifyAndClear(&*main_rfh_output_broker);
   }
   {
     EXPECT_CALL(*other_rfh_output_broker, CreateStream(NotNull()));
     mojo::MakeRequest(&output_client);
     factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams,
-                               std::move(output_client));
+                               base::nullopt, std::move(output_client));
     testing::Mock::VerifyAndClear(&*other_rfh_output_broker);
   }
 
@@ -499,7 +500,7 @@
   EXPECT_CALL(*output_broker, CreateStream(NotNull()));
   mojo::MakeRequest(&output_client);
   factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                             std::move(output_client));
+                             base::nullopt, std::move(output_client));
 
   DeleteContents();
   base::RunLoop().RunUntilIdle();
@@ -547,14 +548,14 @@
     EXPECT_CALL(*main_rfh_output_broker, CreateStream(NotNull()));
     mojo::MakeRequest(&output_client);
     factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                               std::move(output_client));
+                               base::nullopt, std::move(output_client));
     testing::Mock::VerifyAndClear(&*main_rfh_output_broker);
   }
   {
     EXPECT_CALL(*other_rfh_output_broker, CreateStream(NotNull()));
     mojo::MakeRequest(&output_client);
     factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams,
-                               std::move(output_client));
+                               base::nullopt, std::move(output_client));
     testing::Mock::VerifyAndClear(&*other_rfh_output_broker);
   }
 
@@ -606,7 +607,7 @@
   EXPECT_CALL(*broker, CreateStream(NotNull()));
   mojo::MakeRequest(&client);
   factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                             std::move(client));
+                             base::nullopt, std::move(client));
   base::RunLoop().RunUntilIdle();
   testing::Mock::VerifyAndClear(&*broker);
 
@@ -645,7 +646,7 @@
   EXPECT_CALL(*broker, CreateStream(NotNull()));
   mojo::MakeRequest(&client);
   factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                             std::move(client));
+                             base::nullopt, std::move(client));
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(factory.IsMuted());
   EXPECT_TRUE(stream_factory_.IsConnected());
@@ -673,7 +674,7 @@
     EXPECT_CALL(*broker, CreateStream(NotNull()));
     mojo::MakeRequest(&client);
     factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                               std::move(client));
+                               base::nullopt, std::move(client));
     base::RunLoop().RunUntilIdle();
     testing::Mock::VerifyAndClear(&*broker);
   }
@@ -690,7 +691,7 @@
     EXPECT_CALL(*another_broker, CreateStream(NotNull()));
     mojo::MakeRequest(&client);
     factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
-                               std::move(client));
+                               base::nullopt, std::move(client));
     base::RunLoop().RunUntilIdle();
     testing::Mock::VerifyAndClear(&*another_broker);
   }
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc
index aeb2cc3..3e7c521 100644
--- a/content/browser/renderer_host/input/touch_action_filter.cc
+++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -46,15 +46,6 @@
 
 TouchActionFilter::~TouchActionFilter() {}
 
-// In all the places that has DumpWithCrashing(), generate a report once every
-// 100 times.
-bool TouchActionFilter::ShouldDump() {
-  std::uniform_int_distribution<int> uniform_dist(0, 99);
-  if (uniform_dist(gen_) == 0)
-    return true;
-  return false;
-}
-
 FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
     WebGestureEvent* gesture_event) {
   if (gesture_event->SourceDevice() != blink::kWebGestureDeviceTouchscreen)
@@ -67,16 +58,12 @@
       DCHECK(!suppress_manipulation_events_);
       gesture_sequence_in_progress_ = true;
       gesture_sequence_.append("B");
-      // TODO(https://crbug.com/851644): Make sure the value is properly set.
       if (!scrolling_touch_action_.has_value()) {
-        if (ShouldDump()) {
-          static auto* crash_key = base::debug::AllocateCrashKeyString(
-              "scrollbegin-gestures", base::debug::CrashKeySize::Size256);
-          base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
-          base::debug::DumpWithoutCrashing();
-        }
+        static auto* crash_key = base::debug::AllocateCrashKeyString(
+            "scrollbegin-gestures", base::debug::CrashKeySize::Size256);
+        base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
+        base::debug::DumpWithoutCrashing();
         gesture_sequence_.clear();
-        SetTouchAction(cc::kTouchActionAuto);
       }
       suppress_manipulation_events_ =
           ShouldSuppressManipulation(*gesture_event);
@@ -146,16 +133,12 @@
     case WebInputEvent::kGestureTapUnconfirmed: {
       gesture_sequence_.append("C");
       DCHECK_EQ(1, gesture_event->data.tap.tap_count);
-      // TODO(https://crbug.com/851644): Make sure the value is properly set.
       if (!scrolling_touch_action_.has_value()) {
-        if (ShouldDump()) {
-          static auto* crash_key = base::debug::AllocateCrashKeyString(
-              "tapunconfirmed-gestures", base::debug::CrashKeySize::Size256);
-          base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
-          base::debug::DumpWithoutCrashing();
-        }
+        static auto* crash_key = base::debug::AllocateCrashKeyString(
+            "tapunconfirmed-gestures", base::debug::CrashKeySize::Size256);
+        base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
+        base::debug::DumpWithoutCrashing();
         gesture_sequence_.clear();
-        SetTouchAction(cc::kTouchActionAuto);
       }
       allow_current_double_tap_event_ = (scrolling_touch_action_.value() &
                                          cc::kTouchActionDoubleTapZoom) != 0;
@@ -184,16 +167,12 @@
       if (gesture_event->is_source_touch_event_set_non_blocking)
         SetTouchAction(cc::kTouchActionAuto);
       scrolling_touch_action_ = allowed_touch_action_;
-      // TODO(https://crbug.com/851644): Make sure the value is properly set.
       if (!scrolling_touch_action_.has_value()) {
-        if (ShouldDump()) {
-          static auto* crash_key = base::debug::AllocateCrashKeyString(
-              "tapdown-gestures", base::debug::CrashKeySize::Size256);
-          base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
-          base::debug::DumpWithoutCrashing();
-        }
+        static auto* crash_key = base::debug::AllocateCrashKeyString(
+            "tapdown-gestures", base::debug::CrashKeySize::Size256);
+        base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
+        base::debug::DumpWithoutCrashing();
         gesture_sequence_.clear();
-        SetTouchAction(cc::kTouchActionAuto);
       }
       DCHECK(!drop_current_tap_ending_event_);
       break;
diff --git a/content/browser/renderer_host/input/touch_action_filter.h b/content/browser/renderer_host/input/touch_action_filter.h
index 75d0b89e..29db63b 100644
--- a/content/browser/renderer_host/input/touch_action_filter.h
+++ b/content/browser/renderer_host/input/touch_action_filter.h
@@ -5,8 +5,6 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_ACTION_FILTER_H_
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_ACTION_FILTER_H_
 
-#include <random>
-
 #include "base/macros.h"
 #include "base/optional.h"
 #include "cc/input/touch_action.h"
@@ -81,9 +79,6 @@
   void ReportTouchAction();
   void SetTouchAction(cc::TouchAction touch_action);
 
-  // Debugging only.
-  bool ShouldDump();
-
   // Whether scroll and pinch gestures should be discarded due to touch-action.
   bool suppress_manipulation_events_;
 
@@ -124,7 +119,6 @@
 
   // Debugging only.
   std::string gesture_sequence_;
-  std::default_random_engine gen_;
 
   DISALLOW_COPY_AND_ASSIGN(TouchActionFilter);
 };
diff --git a/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
index 77b2cd1..81964504 100644
--- a/content/browser/renderer_host/input/touch_action_filter_unittest.cc
+++ b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
@@ -890,8 +890,8 @@
 
   EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
             FilterGestureEventResult::kFilterGestureEventAllowed);
-  EXPECT_TRUE(filter_.allowed_touch_action().has_value());
-  EXPECT_TRUE(ScrollingTouchAction().has_value());
+  EXPECT_FALSE(filter_.allowed_touch_action().has_value());
+  EXPECT_FALSE(ScrollingTouchAction().has_value());
 }
 
 // This test ensures that when the IPC message OnHasTouchEventHandlers is
diff --git a/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc b/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc
index b4f527a..8277d2d 100644
--- a/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc
+++ b/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc
@@ -235,7 +235,11 @@
             GetTestAudioParameters().AsHumanReadableString());
   EXPECT_TRUE(id.empty());
 
-  provider->Acquire(params, client.MakeProviderClientPtr());
+  // Ensure that we don't blow up getting a processing ID, despite not using it.
+  const base::UnguessableToken kUnusedProcessingId =
+      base::UnguessableToken::Create();
+  provider->Acquire(params, client.MakeProviderClientPtr(),
+                    kUnusedProcessingId);
   base::RunLoop().RunUntilIdle();
   ASSERT_NE(event_handler, nullptr);
 
@@ -295,7 +299,8 @@
                         const std::string& id) {}));
   base::RunLoop().RunUntilIdle();
 
-  provider->Acquire(GetTestAudioParameters(), client.MakeProviderClientPtr());
+  provider->Acquire(GetTestAudioParameters(), client.MakeProviderClientPtr(),
+                    base::nullopt);
   base::RunLoop().RunUntilIdle();
   ASSERT_NE(event_handler, nullptr);
   EXPECT_FALSE(delegate_is_destructed);
@@ -325,7 +330,8 @@
                         const std::string& id) {}));
   base::RunLoop().RunUntilIdle();
 
-  provider->Acquire(GetTestAudioParameters(), client.MakeProviderClientPtr());
+  provider->Acquire(GetTestAudioParameters(), client.MakeProviderClientPtr(),
+                    base::nullopt);
   base::RunLoop().RunUntilIdle();
   ASSERT_NE(event_handler, nullptr);
   EXPECT_FALSE(delegate_is_destructed);
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc
index 00642ad..dadd1cd 100644
--- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc
+++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc
@@ -37,7 +37,8 @@
 
   void Acquire(
       const media::AudioParameters& params,
-      media::mojom::AudioOutputStreamProviderClientPtr provider_client) final {
+      media::mojom::AudioOutputStreamProviderClientPtr provider_client,
+      const base::Optional<base::UnguessableToken>& processing_id) final {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     TRACE_EVENT1("audio",
                  "RenderFrameAudioOutputStreamFactory::ProviderImpl::Acquire",
@@ -50,7 +51,7 @@
       // It's possible that |frame| has already been destroyed, in which case we
       // don't need to create a stream. In this case, the renderer will get a
       // connection error since |provider_client| is dropped.
-      factory->CreateOutputStream(frame, device_id_, params,
+      factory->CreateOutputStream(frame, device_id_, params, processing_id,
                                   std::move(provider_client));
     }
 
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
index 837204a..ed17a87 100644
--- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
+++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
@@ -100,6 +100,7 @@
         const std::string& output_device_id,
         const media::AudioParameters& params,
         const base::UnguessableToken& group_id,
+        const base::Optional<base::UnguessableToken>& processing_id,
         CreateOutputStreamCallback created_callback) override {
       last_created_callback = std::move(created_callback);
     }
@@ -214,7 +215,7 @@
   {
     media::mojom::AudioOutputStreamProviderClientPtr client;
     mojo::MakeRequest(&client);
-    provider_ptr->Acquire(kParams, std::move(client));
+    provider_ptr->Acquire(kParams, std::move(client), base::nullopt);
   }
 
   audio::mojom::StreamFactory::CreateOutputStreamCallback created_callback;
@@ -251,7 +252,7 @@
   {
     media::mojom::AudioOutputStreamProviderClientPtr client;
     mojo::MakeRequest(&client);
-    provider_ptr->Acquire(kParams, std::move(client));
+    provider_ptr->Acquire(kParams, std::move(client), base::nullopt);
   }
 
   base::RunLoop().RunUntilIdle();
diff --git a/content/browser/webauth/authenticator_impl.cc b/content/browser/webauth/authenticator_impl.cc
index 3025e35..99c36edb 100644
--- a/content/browser/webauth/authenticator_impl.cc
+++ b/content/browser/webauth/authenticator_impl.cc
@@ -336,7 +336,12 @@
     protocols_.insert(device::FidoTransportProtocol::kBluetoothLowEnergy);
   }
 
+#if defined(OS_WIN)
+  if (base::FeatureList::IsEnabled(features::kWebAuthCable) &&
+      base::FeatureList::IsEnabled(features::kWebAuthCableWin)) {
+#else
   if (base::FeatureList::IsEnabled(features::kWebAuthCable)) {
+#endif  // defined(OS_WIN)
     protocols_.insert(
         device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy);
   }
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index d55fd0d..2c3c0e3 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -820,7 +820,7 @@
   }
 }
 
-TEST_F(AuthenticatorImplTest, TestCableDiscoveryEnabledByDefault) {
+TEST_F(AuthenticatorImplTest, TestCableDiscoveryByDefault) {
   TestServiceManagerContext service_manager_context;
   SimulateNavigation(GURL(kTestOrigin1));
   PublicKeyCredentialRequestOptionsPtr options =
@@ -838,8 +838,15 @@
   callback_receiver.WaitForCallback();
 
   EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
+
+// On Windows caBLE should be disabled by default.
+#if defined(OS_WIN)
+  EXPECT_FALSE(SupportsTransportProtocol(
+      device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy));
+#else
   EXPECT_TRUE(SupportsTransportProtocol(
       device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy));
+#endif
 }
 
 TEST_F(AuthenticatorImplTest, TestCableDiscoveryDisabledWithoutFlag) {
@@ -866,6 +873,66 @@
       device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy));
 }
 
+#if defined(OS_WIN)
+TEST_F(AuthenticatorImplTest, TestCableDiscoveryEnabledWithWinFlag) {
+  EnableFeature(features::kWebAuthCableWin);
+  TestServiceManagerContext service_manager_context;
+  SimulateNavigation(GURL(kTestOrigin1));
+  PublicKeyCredentialRequestOptionsPtr options =
+      GetTestPublicKeyCredentialRequestOptions();
+  TestGetAssertionCallback callback_receiver;
+
+  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+      base::Time::Now(), base::TimeTicks::Now());
+  auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
+  authenticator->GetAssertion(std::move(options), callback_receiver.callback());
+
+  // Trigger timer.
+  base::RunLoop().RunUntilIdle();
+  task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
+  callback_receiver.WaitForCallback();
+
+  EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
+  EXPECT_TRUE(SupportsTransportProtocol(
+      device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy));
+}
+
+// Tests that caBLE is not supported when features::kWebAuthCable is disabled,
+// regardless of the state of features::kWebAuthCableWin.
+TEST_F(AuthenticatorImplTest, TestCableDiscoveryDisabledWithoutFlagWin) {
+  for (bool enable_win_flag : {false, true}) {
+    std::vector<base::Feature> enabled_features;
+    std::vector<base::Feature> disabled_features = {features::kWebAuthCable};
+    enable_win_flag ? enabled_features.push_back(features::kWebAuthCableWin)
+                    : disabled_features.push_back(features::kWebAuthCableWin);
+
+    scoped_feature_list_.emplace();
+    scoped_feature_list_->InitWithFeatures(enabled_features, disabled_features);
+    TestServiceManagerContext service_manager_context;
+    SimulateNavigation(GURL(kTestOrigin1));
+    PublicKeyCredentialRequestOptionsPtr options =
+        GetTestPublicKeyCredentialRequestOptions();
+    TestGetAssertionCallback callback_receiver;
+
+    auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+        base::Time::Now(), base::TimeTicks::Now());
+    auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
+    authenticator->GetAssertion(std::move(options),
+                                callback_receiver.callback());
+
+    // Trigger timer.
+    base::RunLoop().RunUntilIdle();
+    task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
+    callback_receiver.WaitForCallback();
+
+    EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR,
+              callback_receiver.status());
+    EXPECT_FALSE(SupportsTransportProtocol(
+        device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy));
+  }
+}
+#endif
+
 TEST_F(AuthenticatorImplTest, TestCableDiscoveryDisabledForMakeCredential) {
   SimulateNavigation(GURL(kTestOrigin1));
   PublicKeyCredentialCreationOptionsPtr options =
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 529181a..e99a0b2 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -518,6 +518,12 @@
 const base::Feature kWebAuthCable{"WebAuthenticationCable",
                                   base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Controls whether CTAP2 devices can communicate via the WebAuthentication API
+// using pairingless BLE protocol on Windows.
+// https://w3c.github.io/webauthn
+const base::Feature kWebAuthCableWin{"WebAuthenticationCableWin",
+                                     base::FEATURE_DISABLED_BY_DEFAULT};
+
 // If WebGL Image Chromium is allowed, this feature controls whether it is
 // enabled.
 const base::Feature kWebGLImageChromium{"WebGLImageChromium",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index acfd6e74..71f3f7b1 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -118,6 +118,7 @@
 CONTENT_EXPORT extern const base::Feature kWebAuth;
 CONTENT_EXPORT extern const base::Feature kWebAuthBle;
 CONTENT_EXPORT extern const base::Feature kWebAuthCable;
+CONTENT_EXPORT extern const base::Feature kWebAuthCableWin;
 CONTENT_EXPORT extern const base::Feature kWebContentsOcclusion;
 CONTENT_EXPORT extern const base::Feature kWebGLImageChromium;
 CONTENT_EXPORT extern const base::Feature kWebPayments;
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc.cc b/content/renderer/media/audio/mojo_audio_output_ipc.cc
index 1782dd2..1aa79bbe 100644
--- a/content/renderer/media/audio/mojo_audio_output_ipc.cc
+++ b/content/renderer/media/audio/mojo_audio_output_ipc.cc
@@ -61,8 +61,10 @@
           media::AudioParameters::UnavailableDeviceParams(), std::string()));
 }
 
-void MojoAudioOutputIPC::CreateStream(media::AudioOutputIPCDelegate* delegate,
-                                      const media::AudioParameters& params) {
+void MojoAudioOutputIPC::CreateStream(
+    media::AudioOutputIPCDelegate* delegate,
+    const media::AudioParameters& params,
+    const base::Optional<base::UnguessableToken>& processing_id) {
   DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(delegate);
   DCHECK(!StreamCreationRequested());
@@ -87,7 +89,7 @@
   binding_.set_connection_error_with_reason_handler(
       base::BindOnce(&MojoAudioOutputIPC::ProviderClientBindingDisconnected,
                      base::Unretained(this)));
-  stream_provider_->Acquire(params, std::move(client_ptr));
+  stream_provider_->Acquire(params, std::move(client_ptr), processing_id);
 }
 
 void MojoAudioOutputIPC::PlayStream() {
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc.h b/content/renderer/media/audio/mojo_audio_output_ipc.h
index 00084e5..3770e2a 100644
--- a/content/renderer/media/audio/mojo_audio_output_ipc.h
+++ b/content/renderer/media/audio/mojo_audio_output_ipc.h
@@ -43,8 +43,10 @@
   void RequestDeviceAuthorization(media::AudioOutputIPCDelegate* delegate,
                                   int session_id,
                                   const std::string& device_id) override;
-  void CreateStream(media::AudioOutputIPCDelegate* delegate,
-                    const media::AudioParameters& params) override;
+  void CreateStream(
+      media::AudioOutputIPCDelegate* delegate,
+      const media::AudioParameters& params,
+      const base::Optional<base::UnguessableToken>& processing_id) override;
   void PlayStream() override;
   void PauseStream() override;
   void CloseStream() override;
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc b/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
index 100687c..1f8f1e3d 100644
--- a/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
+++ b/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
@@ -57,9 +57,10 @@
       EXPECT_TRUE(binding_);
   }
 
-  void Acquire(const media::AudioParameters& params,
-               media::mojom::AudioOutputStreamProviderClientPtr provider_client)
-      override {
+  void Acquire(
+      const media::AudioParameters& params,
+      media::mojom::AudioOutputStreamProviderClientPtr provider_client,
+      const base::Optional<base::UnguessableToken>& processing_id) override {
     EXPECT_EQ(binding_, base::nullopt);
     EXPECT_NE(stream_, nullptr);
     std::swap(provider_client, provider_client_);
@@ -228,7 +229,7 @@
           NullAccessor(),
           blink::scheduler::GetSingleThreadTaskRunnerForTesting());
 
-  ipc->CreateStream(&delegate, Params());
+  ipc->CreateStream(&delegate, Params(), base::nullopt);
 
   // No call to OnDeviceAuthorized since authotization wasn't explicitly
   // requested.
@@ -273,7 +274,7 @@
       kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
 
   ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId);
-  ipc->CreateStream(&delegate, Params());
+  ipc->CreateStream(&delegate, Params(), base::nullopt);
 
   EXPECT_CALL(delegate, OnDeviceAuthorized(
                             media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
@@ -304,7 +305,7 @@
       0, std::string(media::AudioDeviceDescription::kDefaultDeviceId),
       std::make_unique<TestStreamProvider>(&stream));
 
-  ipc->CreateStream(&delegate, Params());
+  ipc->CreateStream(&delegate, Params(), base::nullopt);
 
   EXPECT_CALL(delegate, GotOnStreamCreated());
   base::RunLoop().RunUntilIdle();
@@ -329,7 +330,7 @@
         kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
 
     ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId);
-    ipc->CreateStream(&delegate, Params());
+    ipc->CreateStream(&delegate, Params(), base::nullopt);
 
     EXPECT_CALL(
         delegate,
@@ -377,7 +378,7 @@
         kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
 
     ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId);
-    ipc->CreateStream(&delegate, Params());
+    ipc->CreateStream(&delegate, Params(), base::nullopt);
 
     EXPECT_CALL(
         delegate,
@@ -519,7 +520,7 @@
           stream_factory.GetAccessor(),
           blink::scheduler::GetSingleThreadTaskRunnerForTesting());
 
-  ipc->CreateStream(&delegate, Params());
+  ipc->CreateStream(&delegate, Params(), base::nullopt);
   EXPECT_DCHECK_DEATH(ipc.reset());
   ipc->CloseStream();
   ipc.reset();
@@ -546,7 +547,7 @@
       kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
 
   ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId);
-  ipc->CreateStream(&delegate, Params());
+  ipc->CreateStream(&delegate, Params(), base::nullopt);
   base::RunLoop().RunUntilIdle();
   ipc->PlayStream();
   base::RunLoop().RunUntilIdle();
@@ -574,7 +575,7 @@
       kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
 
   ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId);
-  ipc->CreateStream(&delegate, Params());
+  ipc->CreateStream(&delegate, Params(), base::nullopt);
   base::RunLoop().RunUntilIdle();
   ipc->PauseStream();
   base::RunLoop().RunUntilIdle();
@@ -602,7 +603,7 @@
       kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
 
   ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId);
-  ipc->CreateStream(&delegate, Params());
+  ipc->CreateStream(&delegate, Params(), base::nullopt);
   base::RunLoop().RunUntilIdle();
   ipc->SetVolume(kNewVolume);
   base::RunLoop().RunUntilIdle();
diff --git a/content/renderer/pepper/pepper_platform_audio_output.cc b/content/renderer/pepper/pepper_platform_audio_output.cc
index fcc69c75..3e5586d 100644
--- a/content/renderer/pepper/pepper_platform_audio_output.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output.cc
@@ -154,7 +154,7 @@
     const media::AudioParameters& params) {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
   if (ipc_)
-    ipc_->CreateStream(this, params);
+    ipc_->CreateStream(this, params, base::nullopt);
 }
 
 void PepperPlatformAudioOutput::StartPlaybackOnIOThread() {
diff --git a/content/renderer/pepper/pepper_platform_audio_output_dev.cc b/content/renderer/pepper/pepper_platform_audio_output_dev.cc
index aff362b2..3120c80e 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_dev.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output_dev.cc
@@ -310,7 +310,7 @@
     case IDLE:
       if (did_receive_auth_.IsSignaled() && device_id_.empty()) {
         state_ = CREATING_STREAM;
-        ipc_->CreateStream(this, params);
+        ipc_->CreateStream(this, params, base::nullopt);
       } else {
         RequestDeviceAuthorizationOnIOThread();
         start_on_authorized_ = true;
@@ -323,7 +323,7 @@
 
     case AUTHORIZED:
       state_ = CREATING_STREAM;
-      ipc_->CreateStream(this, params);
+      ipc_->CreateStream(this, params, base::nullopt);
       start_on_authorized_ = false;
       break;
 
diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc
index 7ce82fc..a443aef 100644
--- a/device/bluetooth/bluetooth_device_unittest.cc
+++ b/device/bluetooth/bluetooth_device_unittest.cc
@@ -1159,7 +1159,7 @@
   EXPECT_TRUE(device->IsConnected());
   EXPECT_TRUE(device->IsGattConnected());
 
-  SimulateGattDisconnection(device);
+  SimulateDeviceBreaksConnection(device);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, observer.device_changed_count());
   EXPECT_FALSE(device->IsConnected());
@@ -1859,7 +1859,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, gatt_discovery_attempts_);
 
-  SimulateGattDisconnection(device);
+  SimulateDeviceBreaksConnection(device);
   base::RunLoop().RunUntilIdle();
 
   SimulateGattServicesDiscovered(
diff --git a/device/bluetooth/bluetooth_device_winrt.cc b/device/bluetooth/bluetooth_device_winrt.cc
index d7ebde7f..0313a90e 100644
--- a/device/bluetooth/bluetooth_device_winrt.cc
+++ b/device/bluetooth/bluetooth_device_winrt.cc
@@ -450,7 +450,20 @@
 }
 
 void BluetoothDeviceWinrt::DisconnectGatt() {
+  // Closing the device and disposing of all references will trigger a Gatt
+  // Disconnection after a short timeout. Since the Gatt Services store a
+  // reference to |ble_device_| as well, we need to clear them to drop all
+  // remaining references, so that the OS disconnects.
+  // Reference:
+  // - https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/gatt-client
   CloseDevice(ble_device_);
+  ClearGattServices();
+
+  // Stop any pending Gatt Discovery sessions and report an error. This will
+  // destroy |gatt_discoverer_| and release remaining references the discoverer
+  // might have hold.
+  if (gatt_discoverer_)
+    OnGattDiscoveryComplete(false);
 }
 
 HRESULT BluetoothDeviceWinrt::GetBluetoothLEDeviceStaticsActivationFactory(
@@ -517,9 +530,7 @@
     DidConnectGatt();
   } else {
     gatt_discoverer_.reset();
-    gatt_services_.clear();
-    device_uuids_.ClearServiceUUIDs();
-    SetGattServicesDiscoveryComplete(false);
+    ClearGattServices();
     DidDisconnectGatt();
   }
 }
@@ -527,6 +538,8 @@
 void BluetoothDeviceWinrt::OnGattServicesChanged(IBluetoothLEDevice* ble_device,
                                                  IInspectable* object) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  // Note: We don't clear out |gatt_services_| here, as we don't want to break
+  // existing references to Gatt Services that did not change.
   device_uuids_.ClearServiceUUIDs();
   SetGattServicesDiscoveryComplete(false);
   adapter_->NotifyDeviceChanged(this);
@@ -581,4 +594,10 @@
   gatt_discoverer_.reset();
 }
 
+void BluetoothDeviceWinrt::ClearGattServices() {
+  gatt_services_.clear();
+  device_uuids_.ClearServiceUUIDs();
+  SetGattServicesDiscoveryComplete(false);
+}
+
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_device_winrt.h b/device/bluetooth/bluetooth_device_winrt.h
index 390b626..93644ab6 100644
--- a/device/bluetooth/bluetooth_device_winrt.h
+++ b/device/bluetooth/bluetooth_device_winrt.h
@@ -119,11 +119,7 @@
 
   void OnGattDiscoveryComplete(bool success);
 
-  void OnPairingRequested(
-      ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing*
-          custom_pairing,
-      ABI::Windows::Devices::Enumeration::IDevicePairingRequestedEventArgs*
-          event_args);
+  void ClearGattServices();
 
   uint64_t raw_address_;
   std::string address_;
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc
index cb4fd29b..e6c286b 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc
@@ -585,7 +585,7 @@
 #endif
 
   ASSERT_EQ(1u, adapter_->GetDevices().size());
-  SimulateGattDisconnection(adapter_->GetDevices()[0]);
+  SimulateDeviceBreaksConnection(adapter_->GetDevices()[0]);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED,
@@ -677,7 +677,7 @@
 #endif  // defined(OS_ANDROID)
 
   ASSERT_EQ(1u, adapter_->GetDevices().size());
-  SimulateGattDisconnection(adapter_->GetDevices()[0]);
+  SimulateDeviceBreaksConnection(adapter_->GetDevices()[0]);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED,
@@ -3321,7 +3321,7 @@
   characteristic1_->WriteRemoteCharacteristic(
       std::vector<uint8_t>(), GetCallback(Call::NOT_EXPECTED),
       GetGattErrorCallback(Call::EXPECTED));
-  SimulateGattDisconnection(device_);
+  SimulateDeviceBreaksConnection(adapter_->GetDevices()[0]);
 
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED,
diff --git a/device/bluetooth/test/bluetooth_test.cc b/device/bluetooth/test/bluetooth_test.cc
index b0cdb67..e19e1f1 100644
--- a/device/bluetooth/test/bluetooth_test.cc
+++ b/device/bluetooth/test/bluetooth_test.cc
@@ -110,6 +110,11 @@
   return nullptr;
 }
 
+void BluetoothTestBase::SimulateDeviceBreaksConnection(
+    BluetoothDevice* device) {
+  SimulateGattDisconnection(device);
+}
+
 bool BluetoothTestBase::SimulateLocalGattCharacteristicNotificationsRequest(
     BluetoothLocalGattCharacteristic* characteristic,
     bool start) {
diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h
index 7fdb898..f00c201 100644
--- a/device/bluetooth/test/bluetooth_test.h
+++ b/device/bluetooth/test/bluetooth_test.h
@@ -272,6 +272,10 @@
   // Simulates GattConnection disconnecting.
   virtual void SimulateGattDisconnection(BluetoothDevice* device) {}
 
+  // Simulates an event where the OS breaks the Gatt connection. Defaults to
+  // SimulateGattDisconnection(device).
+  virtual void SimulateDeviceBreaksConnection(BluetoothDevice* device);
+
   // Simulates success of discovering services. |uuids| is used to create a
   // service for each UUID string. Multiple UUIDs with the same value produce
   // multiple service instances.
diff --git a/device/bluetooth/test/bluetooth_test_win.cc b/device/bluetooth/test/bluetooth_test_win.cc
index faeb2ccd..2f74af50 100644
--- a/device/bluetooth/test/bluetooth_test_win.cc
+++ b/device/bluetooth/test/bluetooth_test_win.cc
@@ -718,6 +718,14 @@
   ble_device->SimulateGattDisconnection();
 }
 
+void BluetoothTestWinrt::SimulateDeviceBreaksConnection(
+    BluetoothDevice* device) {
+  auto* const ble_device =
+      static_cast<TestBluetoothDeviceWinrt*>(device)->ble_device();
+  DCHECK(ble_device);
+  ble_device->SimulateDeviceBreaksConnection();
+}
+
 void BluetoothTestWinrt::SimulateGattServicesDiscovered(
     BluetoothDevice* device,
     const std::vector<std::string>& uuids) {
diff --git a/device/bluetooth/test/bluetooth_test_win.h b/device/bluetooth/test/bluetooth_test_win.h
index 55df889..ca84dfa 100644
--- a/device/bluetooth/test/bluetooth_test_win.h
+++ b/device/bluetooth/test/bluetooth_test_win.h
@@ -130,6 +130,7 @@
       BluetoothDevice* device,
       BluetoothDevice::ConnectErrorCode error_code) override;
   void SimulateGattDisconnection(BluetoothDevice* device) override;
+  void SimulateDeviceBreaksConnection(BluetoothDevice* device) override;
   void SimulateGattServicesDiscovered(
       BluetoothDevice* device,
       const std::vector<std::string>& uuids) override;
diff --git a/device/bluetooth/test/fake_bluetooth_le_device_winrt.cc b/device/bluetooth/test/fake_bluetooth_le_device_winrt.cc
index 25611f90..707abc8 100644
--- a/device/bluetooth/test/fake_bluetooth_le_device_winrt.cc
+++ b/device/bluetooth/test/fake_bluetooth_le_device_winrt.cc
@@ -183,10 +183,20 @@
 }
 
 HRESULT FakeBluetoothLEDeviceWinrt::Close() {
+  --reference_count_;
+  fake_services_.clear();
   bluetooth_test_winrt_->OnFakeBluetoothGattDisconnect();
   return S_OK;
 }
 
+void FakeBluetoothLEDeviceWinrt::AddReference() {
+  ++reference_count_;
+}
+
+void FakeBluetoothLEDeviceWinrt::RemoveReference() {
+  --reference_count_;
+}
+
 void FakeBluetoothLEDeviceWinrt::SimulateDevicePaired(bool is_paired) {
   device_information_ = Make<FakeDeviceInformationWinrt>(
       Make<FakeDeviceInformationPairingWinrt>(is_paired));
@@ -221,6 +231,24 @@
     return;
   }
 
+  // Simulate production UWP behavior that only really disconnects once all
+  // references to a device are dropped.
+  if (reference_count_ == 0u) {
+    status_ = BluetoothConnectionStatus_Disconnected;
+    connection_status_changed_handler_->Invoke(this, nullptr);
+  }
+}
+
+void FakeBluetoothLEDeviceWinrt::SimulateDeviceBreaksConnection() {
+  if (status_ == BluetoothConnectionStatus_Disconnected) {
+    DCHECK(gatt_services_callback_);
+    std::move(gatt_services_callback_)
+        .Run(Make<FakeGattDeviceServicesResultWinrt>(
+            GattCommunicationStatus_Unreachable));
+    return;
+  }
+
+  // Simulate a Gatt Disconnecion regardless of the reference count.
   status_ = BluetoothConnectionStatus_Disconnected;
   connection_status_changed_handler_->Invoke(this, nullptr);
 }
@@ -231,8 +259,9 @@
     // Attribute handles need to be unique for a given BLE device. Increasing by
     // a large number ensures enough address space for the contained
     // characteristics and descriptors.
-    fake_services_.push_back(Make<FakeGattDeviceServiceWinrt>(
-        bluetooth_test_winrt_, uuid, service_attribute_handle_ += 0x0400));
+    fake_services_.push_back(
+        Make<FakeGattDeviceServiceWinrt>(bluetooth_test_winrt_, this, uuid,
+                                         service_attribute_handle_ += 0x0400));
   }
 
   DCHECK(gatt_services_callback_);
diff --git a/device/bluetooth/test/fake_bluetooth_le_device_winrt.h b/device/bluetooth/test/fake_bluetooth_le_device_winrt.h
index b4688488..75486fe 100644
--- a/device/bluetooth/test/fake_bluetooth_le_device_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_le_device_winrt.h
@@ -114,12 +114,19 @@
   // IClosable:
   IFACEMETHODIMP Close() override;
 
+  // We perform explicit reference counting, to be able to query the ref count
+  // ourselves. This is required to simulate Gatt disconnection behavior
+  // exhibited by the production UWP APIs.
+  void AddReference();
+  void RemoveReference();
+
   void SimulateDevicePaired(bool is_paired);
   void SimulatePairingPinCode(std::string pin_code);
   void SimulateGattConnection();
   void SimulateGattConnectionError(
       BluetoothDevice::ConnectErrorCode error_code);
   void SimulateGattDisconnection();
+  void SimulateDeviceBreaksConnection();
   void SimulateGattServicesDiscovered(const std::vector<std::string>& uuids);
   void SimulateGattServicesChanged();
   void SimulateGattServiceRemoved(BluetoothRemoteGattService* service);
@@ -132,6 +139,7 @@
 
  private:
   BluetoothTestWinrt* bluetooth_test_winrt_ = nullptr;
+  uint32_t reference_count_ = 1u;
 
   ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus status_ =
       ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus_Disconnected;
diff --git a/device/bluetooth/test/fake_gatt_device_service_winrt.cc b/device/bluetooth/test/fake_gatt_device_service_winrt.cc
index 7a1d7ac..772c18d 100644
--- a/device/bluetooth/test/fake_gatt_device_service_winrt.cc
+++ b/device/bluetooth/test/fake_gatt_device_service_winrt.cc
@@ -14,6 +14,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/win/async_operation.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/test/fake_bluetooth_le_device_winrt.h"
 #include "device/bluetooth/test/fake_gatt_characteristic_winrt.h"
 #include "device/bluetooth/test/fake_gatt_characteristics_result_winrt.h"
 
@@ -38,20 +39,27 @@
 using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation;
 using ABI::Windows::Foundation::Collections::IVectorView;
 using ABI::Windows::Foundation::IAsyncOperation;
+using Microsoft::WRL::ComPtr;
 using Microsoft::WRL::Make;
 
 }  // namespace
 
 FakeGattDeviceServiceWinrt::FakeGattDeviceServiceWinrt(
     BluetoothTestWinrt* bluetooth_test_winrt,
+    ComPtr<FakeBluetoothLEDeviceWinrt> fake_device,
     base::StringPiece uuid,
     uint16_t attribute_handle)
     : bluetooth_test_winrt_(bluetooth_test_winrt),
+      fake_device_(std::move(fake_device)),
       uuid_(BluetoothUUID::GetCanonicalValueAsGUID(uuid)),
       attribute_handle_(attribute_handle),
-      characteristic_attribute_handle_(attribute_handle_) {}
+      characteristic_attribute_handle_(attribute_handle_) {
+  fake_device_->AddReference();
+}
 
-FakeGattDeviceServiceWinrt::~FakeGattDeviceServiceWinrt() = default;
+FakeGattDeviceServiceWinrt::~FakeGattDeviceServiceWinrt() {
+  fake_device_->RemoveReference();
+}
 
 HRESULT FakeGattDeviceServiceWinrt::GetCharacteristics(
     GUID characteristic_uuid,
diff --git a/device/bluetooth/test/fake_gatt_device_service_winrt.h b/device/bluetooth/test/fake_gatt_device_service_winrt.h
index 66dcb359..9c0c38e 100644
--- a/device/bluetooth/test/fake_gatt_device_service_winrt.h
+++ b/device/bluetooth/test/fake_gatt_device_service_winrt.h
@@ -19,6 +19,7 @@
 namespace device {
 
 class BluetoothTestWinrt;
+class FakeBluetoothLEDeviceWinrt;
 class FakeGattCharacteristicWinrt;
 
 class FakeGattDeviceServiceWinrt
@@ -30,9 +31,11 @@
           ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
               IGattDeviceService3> {
  public:
-  FakeGattDeviceServiceWinrt(BluetoothTestWinrt* bluetooth_test_winrt,
-                             base::StringPiece uuid,
-                             uint16_t attribute_handle);
+  FakeGattDeviceServiceWinrt(
+      BluetoothTestWinrt* bluetooth_test_winrt,
+      Microsoft::WRL::ComPtr<FakeBluetoothLEDeviceWinrt> fake_device,
+      base::StringPiece uuid,
+      uint16_t attribute_handle);
   ~FakeGattDeviceServiceWinrt() override;
 
   // IGattDeviceService:
@@ -115,6 +118,7 @@
 
  private:
   BluetoothTestWinrt* bluetooth_test_winrt_;
+  Microsoft::WRL::ComPtr<FakeBluetoothLEDeviceWinrt> fake_device_;
   GUID uuid_;
   uint16_t attribute_handle_;
 
diff --git a/device/fido/fido_request_handler.h b/device/fido/fido_request_handler.h
index 406c775..00cf754 100644
--- a/device/fido/fido_request_handler.h
+++ b/device/fido/fido_request_handler.h
@@ -58,9 +58,9 @@
       return;
     }
 
-    const auto return_code = ConvertDeviceResponseCodeToFidoReturnCode(
-        device_response_code, response_data.has_value(),
-        authenticator->AuthenticatorTransport());
+    base::Optional<FidoReturnCode> return_code =
+        ConvertDeviceResponseCodeToFidoReturnCode(device_response_code,
+                                                  response_data.has_value());
 
     // Any authenticator response codes that do not result from user consent
     // imply that the authenticator should be dropped and that other on-going
@@ -82,8 +82,7 @@
   static base::Optional<FidoReturnCode>
   ConvertDeviceResponseCodeToFidoReturnCode(
       CtapDeviceResponseCode device_response_code,
-      bool response_has_value,
-      FidoTransportProtocol transport) {
+      bool response_has_value) {
     switch (device_response_code) {
       case CtapDeviceResponseCode::kSuccess:
         return response_has_value
@@ -97,21 +96,11 @@
       case CtapDeviceResponseCode::kCtap2ErrNoCredentials:
         return FidoReturnCode::kUserConsentButCredentialNotRecognized;
 
-      // The user explicitly denied the operation.
+      // The user explicitly denied the operation. Touch ID returns this error
+      // when the user cancels the macOS prompt. External authenticators may
+      // return it e.g. after the user fails fingerprint verification.
       case CtapDeviceResponseCode::kCtap2ErrOperationDenied:
-        // TODO(crbug/875982): Clarify if |CTAP2_ERR_OPERATION_DENIED| is "a
-        // status indicating that the user cancelled the operation" in the
-        // spirit of https://www.w3.org/TR/webauthn/, sections 5.1.3 and
-        // 5.1.4.. The CTAP2 spec also uses it for authenticator-chosen
-        // timeouts, so it is a little unclear.
-        //
-        // For Touch ID, we know it means that the operation failed during (or
-        // after) user verification, so we do the translation the internal
-        // transport only.
-        return transport == FidoTransportProtocol::kInternal
-                   ? base::make_optional<FidoReturnCode>(
-                         FidoReturnCode::kUserConsentDenied)
-                   : base::nullopt;
+        return FidoReturnCode::kUserConsentDenied;
 
       // This error is returned by some authenticators (e.g. the "Yubico FIDO
       // 2" CTAP2 USB keys) during GetAssertion **before the user interacted
diff --git a/device/fido/fido_request_handler_unittest.cc b/device/fido/fido_request_handler_unittest.cc
index 099070f7..943e0d76 100644
--- a/device/fido/fido_request_handler_unittest.cc
+++ b/device/fido/fido_request_handler_unittest.cc
@@ -431,10 +431,8 @@
   EXPECT_EQ(FidoReturnCode::kUserConsentDenied, callback().status());
 }
 
-// Like |TestRequestWithOperationDeniedErrorInternalTransport|, but the
-// CTAP2_ERR_OPERATION_DENIED error is returned by a device with
-// cross-platform transport. The operation should not be cancelled (see
-// https://crbug/875982).
+// Like |TestRequestWithOperationDeniedErrorInternalTransport|, but with a
+// cross-platform authenticator.
 TEST_F(FidoRequestHandlerTest,
        TestRequestWithOperationDeniedErrorCrossPlatform) {
   auto request_handler = CreateFakeHandler();
@@ -446,21 +444,17 @@
   device0->ExpectRequestAndRespondWith(std::vector<uint8_t>(),
                                        CreateFakeOperationDeniedError());
 
-  // Pending device will *NOT* be cancelled and can send a success reply
-  // eventually.
   auto device1 = MockFidoDevice::MakeCtapWithGetInfoExpectation();
-  device1->ExpectRequestAndRespondWith(std::vector<uint8_t>(),
-                                       CreateFakeSuccessDeviceResponse(),
-                                       base::TimeDelta::FromMicroseconds(10));
+  device1->ExpectRequestAndDoNotRespond(std::vector<uint8_t>());
+  EXPECT_CALL(*device1, Cancel());
 
   discovery()->AddDevice(std::move(device0));
   discovery()->AddDevice(std::move(device1));
 
-  // The request will stay pending, the reply has not triggered the callback.
   scoped_task_environment_.FastForwardUntilNoTasksRemain();
   callback().WaitForCallback();
   EXPECT_TRUE(request_handler->is_complete());
-  EXPECT_EQ(FidoReturnCode::kSuccess, callback().status());
+  EXPECT_EQ(FidoReturnCode::kUserConsentDenied, callback().status());
 }
 
 // Requests should be dispatched to the authenticator passed to
diff --git a/device/fido/get_assertion_handler_unittest.cc b/device/fido/get_assertion_handler_unittest.cc
index 57c284c8..6e07287 100644
--- a/device/fido/get_assertion_handler_unittest.cc
+++ b/device/fido/get_assertion_handler_unittest.cc
@@ -620,8 +620,7 @@
 }
 
 // Like |TestRequestWithOperationDeniedErrorPlatform|, but with a
-// cross-platform device. The request should not complete after the
-// CTAP2_ERR_OPERATION_DENIED error (see https://crbug/875982).
+// cross-platform device.
 TEST_F(FidoGetAssertionHandlerTest,
        TestRequestWithOperationDeniedErrorCrossPlatform) {
   auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation();
@@ -634,7 +633,9 @@
   discovery()->AddDevice(std::move(device));
 
   scoped_task_environment_.FastForwardUntilNoTasksRemain();
-  EXPECT_FALSE(get_assertion_callback().was_called());
+  EXPECT_TRUE(get_assertion_callback().was_called());
+  EXPECT_EQ(FidoReturnCode::kUserConsentDenied,
+            get_assertion_callback().status());
 }
 
 }  // namespace device
diff --git a/device/fido/make_credential_handler_unittest.cc b/device/fido/make_credential_handler_unittest.cc
index ae20083e..dd1903e0 100644
--- a/device/fido/make_credential_handler_unittest.cc
+++ b/device/fido/make_credential_handler_unittest.cc
@@ -562,8 +562,7 @@
 }
 
 // Like |TestRequestWithOperationDeniedErrorPlatform|, but with a
-// cross-platform device. The request should not complete after the
-// CTAP2_ERR_OPERATION_DENIED error (see https://crbug/875982).
+// cross-platform device.
 TEST_F(FidoMakeCredentialHandlerTest,
        TestRequestWithOperationDeniedErrorCrossPlatform) {
   auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation();
@@ -582,7 +581,8 @@
   discovery()->AddDevice(std::move(device));
 
   scoped_task_environment_.FastForwardUntilNoTasksRemain();
-  EXPECT_FALSE(callback().was_called());
+  EXPECT_TRUE(callback().was_called());
+  EXPECT_EQ(FidoReturnCode::kUserConsentDenied, callback().status());
 }
 
 }  // namespace device
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index e10ca3e3..75e3291 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -793,7 +793,7 @@
         Sync and Personalization
       </message>
       <message name="IDS_IOS_GOOGLE_SERVICES_SETTINGS_NON_PERSONALIZED_SERVICES_TEXT" desc="Section title for the list of all the non-personalized features to enable/disable in the settings. Related to 'Communicates with Google to improve browsing and Chrome'. [iOS only]">
-        Non-personalized Services
+        Other Google Services
       </message>
       <message name="IDS_IOS_GOOGLE_SERVICES_SETTINGS_TITLE" desc="Title for the view in the Settings for enabling/disabling Sync and all the Google services. [Length: 26em] [iOS only]">
         Sync and Google Services
diff --git a/ios/chrome/browser/metrics/ukm_url_recorder.mm b/ios/chrome/browser/metrics/ukm_url_recorder.mm
index 1d221de05..67c7df1 100644
--- a/ios/chrome/browser/metrics/ukm_url_recorder.mm
+++ b/ios/chrome/browser/metrics/ukm_url_recorder.mm
@@ -134,13 +134,18 @@
   if (!ukm_recorder)
     return;
 
-  const SourceId source_id = ConvertToSourceId(
-      navigation_context->GetNavigationId(), SourceIdType::NAVIGATION_ID);
-  ukm_recorder->UpdateNavigationURL(source_id, initial_url);
-
   const GURL& final_url = navigation_context->GetUrl();
+
+  UkmSource::NavigationData navigation_data;
+  navigation_data.url = final_url;
   if (final_url != initial_url)
-    ukm_recorder->UpdateNavigationURL(source_id, final_url);
+    navigation_data.initial_url = initial_url;
+
+  // TODO(crbug.com/873316): Fill out the other fields in NavigationData.
+
+  const ukm::SourceId source_id = ukm::ConvertToSourceId(
+      navigation_context->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID);
+  ukm_recorder->RecordNavigation(source_id, navigation_data);
 }
 
 }  // namespace internal
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
index e0848c79..3512237 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
@@ -18,12 +18,19 @@
 @interface UnifiedConsentCoordinator ()<IdentityChooserCoordinatorDelegate,
                                         UnifiedConsentViewControllerDelegate>
 
+// Unified consent mediator.
 @property(nonatomic, strong) UnifiedConsentMediator* unifiedConsentMediator;
-@property(nonatomic, strong, readwrite)
+// Unified consent view controller.
+@property(nonatomic, strong)
     UnifiedConsentViewController* unifiedConsentViewController;
-@property(nonatomic, readwrite) BOOL settingsLinkWasTapped;
+// YES if the user tapped on the setting link.
+@property(nonatomic, assign) BOOL settingsLinkWasTapped;
+// Identity chooser coordinator.
 @property(nonatomic, strong)
     IdentityChooserCoordinator* identityChooserCoordinator;
+// YES if no default identity as been set before starting the coordinator.
+@property(nonatomic, assign) BOOL shouldOpenIdentityChooserDialogWhenAppearing;
+
 @end
 
 @implementation UnifiedConsentCoordinator
@@ -34,6 +41,8 @@
 @synthesize settingsLinkWasTapped = _settingsLinkWasTapped;
 @synthesize interactable = _interactable;
 @synthesize identityChooserCoordinator = _identityChooserCoordinator;
+@synthesize shouldOpenIdentityChooserDialogWhenAppearing =
+    _shouldOpenIdentityChooserDialogWhenAppearing;
 
 - (instancetype)init {
   self = [super init];
@@ -48,6 +57,11 @@
 
 - (void)start {
   self.unifiedConsentViewController.interactable = self.interactable;
+  // If no selected identity has been set, the identity chooser dialog needs
+  // to be opened when the view will appear. This test has to be done before
+  // to start the mediator since it will select a default one on start.
+  self.shouldOpenIdentityChooserDialogWhenAppearing =
+      !self.unifiedConsentMediator.selectedIdentity;
   [self.unifiedConsentMediator start];
 }
 
@@ -79,8 +93,30 @@
   return self.unifiedConsentViewController.isScrolledToBottom;
 }
 
+#pragma mark - Private
+
+// Opens the identity chooser dialog with an animation from |point|.
+- (void)showIdentityChooserDialogWithPoint:(CGPoint)point {
+  self.identityChooserCoordinator = [[IdentityChooserCoordinator alloc]
+      initWithBaseViewController:self.unifiedConsentViewController];
+  self.identityChooserCoordinator.delegate = self;
+  self.identityChooserCoordinator.origin = point;
+  [self.identityChooserCoordinator start];
+  self.identityChooserCoordinator.selectedIdentity = self.selectedIdentity;
+}
+
 #pragma mark - UnifiedConsentViewControllerDelegate
 
+- (void)unifiedConsentViewControllerViewDidAppear:
+    (UnifiedConsentViewController*)controller {
+  if (!self.shouldOpenIdentityChooserDialogWhenAppearing)
+    return;
+  CGFloat midX = CGRectGetMidX(self.unifiedConsentViewController.view.bounds);
+  CGFloat midY = CGRectGetMidY(self.unifiedConsentViewController.view.bounds);
+  CGPoint point = CGPointMake(midX, midY);
+  [self showIdentityChooserDialogWithPoint:point];
+}
+
 - (void)unifiedConsentViewControllerDidTapSettingsLink:
     (UnifiedConsentViewController*)controller {
   DCHECK_EQ(self.unifiedConsentViewController, controller);
@@ -93,12 +129,7 @@
             (UnifiedConsentViewController*)controller
                                                      atPoint:(CGPoint)point {
   DCHECK_EQ(self.unifiedConsentViewController, controller);
-  self.identityChooserCoordinator = [[IdentityChooserCoordinator alloc]
-      initWithBaseViewController:self.unifiedConsentViewController];
-  self.identityChooserCoordinator.delegate = self;
-  self.identityChooserCoordinator.origin = point;
-  [self.identityChooserCoordinator start];
-  self.identityChooserCoordinator.selectedIdentity = self.selectedIdentity;
+  [self showIdentityChooserDialogWithPoint:point];
 }
 
 - (void)unifiedConsentViewControllerDidReachBottom:
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
index 03a2644..2bfe83e 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
@@ -20,9 +20,13 @@
   std::unique_ptr<ChromeBrowserProviderObserverBridge> _browserProviderObserver;
 }
 
+// Unified consent view controller.
 @property(nonatomic, weak)
     UnifiedConsentViewController* unifiedConsentViewController;
+// Image for the selected identity avatar.
 @property(nonatomic, strong) UIImage* selectedIdentityAvatar;
+// NO until the mediator is started.
+@property(nonatomic, assign) BOOL started;
 
 @end
 
@@ -31,6 +35,7 @@
 @synthesize selectedIdentityAvatar = _selectedIdentityAvatar;
 @synthesize selectedIdentity = _selectedIdentity;
 @synthesize unifiedConsentViewController = _unifiedConsentViewController;
+@synthesize started = _started;
 
 - (instancetype)initWithUnifiedConsentViewController:
     (UnifiedConsentViewController*)viewController {
@@ -41,12 +46,6 @@
         std::make_unique<ChromeIdentityServiceObserverBridge>(self);
     _browserProviderObserver =
         std::make_unique<ChromeBrowserProviderObserverBridge>(self);
-    NSArray* identities = ios::GetChromeBrowserProvider()
-                              ->GetChromeIdentityService()
-                              ->GetAllIdentitiesSortedForDisplay();
-    if (identities.count != 0) {
-      _selectedIdentity = identities[0];
-    }
   }
   return self;
 }
@@ -65,14 +64,25 @@
 }
 
 - (void)start {
+  NSArray* identities = ios::GetChromeBrowserProvider()
+                            ->GetChromeIdentityService()
+                            ->GetAllIdentitiesSortedForDisplay();
+  if (identities.count != 0) {
+    self.selectedIdentity = identities[0];
+  }
   // Make sure the view is loaded so the mediator can set it up.
   [self.unifiedConsentViewController loadViewIfNeeded];
+  self.started = YES;
   [self updateViewController];
 }
 
 #pragma mark - Private
 
+// Updates the view if the mediator has been started.
 - (void)updateViewController {
+  // The UI should not be updated before the view is loaded.
+  if (!self.started)
+    return;
   if (self.selectedIdentity) {
     [self.unifiedConsentViewController
         updateIdentityPickerViewWithUserFullName:self.selectedIdentity
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
index b5b9f05..567c022 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
@@ -325,6 +325,10 @@
   [self updateScrollViewAndImageBackgroundView];
 }
 
+- (void)viewDidAppear:(BOOL)animated {
+  [self.delegate unifiedConsentViewControllerViewDidAppear:self];
+}
+
 // Updates the scroll view content inset, used by pre iOS 11.
 - (void)viewWillTransitionToSize:(CGSize)size
        withTransitionCoordinator:
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller_delegate.h b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller_delegate.h
index 60e5d53..6974c721 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller_delegate.h
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller_delegate.h
@@ -27,6 +27,10 @@
 - (void)unifiedConsentViewControllerDidReachBottom:
     (UnifiedConsentViewController*)controller;
 
+// Called when the view appears.
+- (void)unifiedConsentViewControllerViewDidAppear:
+    (UnifiedConsentViewController*)controller;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
index eb3fb9b3..3ab820a 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
@@ -515,6 +515,14 @@
   }
 }
 
+- (void)textFieldDidBeginEditing:(UITextField*)textField {
+  textField.textColor = [BookmarkTextFieldCell textColorForEditing:YES];
+}
+
+- (void)textFieldDidEndEditing:(UITextField*)textField {
+  textField.textColor = [BookmarkTextFieldCell textColorForEditing:NO];
+}
+
 - (BOOL)textFieldShouldReturn:(UITextField*)textField {
   [textField resignFirstResponder];
   return YES;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
index 44b4e8e..d4ba7e7a 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
@@ -387,6 +387,14 @@
   [self updateSaveButtonState];
 }
 
+- (void)textFieldDidBeginEditing:(UITextField*)textField {
+  textField.textColor = [BookmarkTextFieldCell textColorForEditing:YES];
+}
+
+- (void)textFieldDidEndEditing:(UITextField*)textField {
+  textField.textColor = [BookmarkTextFieldCell textColorForEditing:NO];
+}
+
 - (BOOL)textFieldShouldReturn:(UITextField*)textField {
   [textField resignFirstResponder];
   return YES;
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h
index 20eb2a3..5f766d8 100644
--- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h
+++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h
@@ -42,6 +42,9 @@
 // Text field to display the title or the URL of the bookmark node.
 @property(nonatomic, strong) UITextField* textField;
 
+// Returns the appropriate text color to use for the given |editing| state.
++ (UIColor*)textColorForEditing:(BOOL)editing;
+
 @end
 
 @interface LegacyBookmarkTextFieldCell : UITableViewCell
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm
index 0e58c07..681c086 100644
--- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm
+++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm
@@ -112,7 +112,7 @@
   self.textField = [[UITextField alloc] init];
   self.textField.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
   self.textField.adjustsFontForContentSizeCategory = YES;
-  self.textField.textColor = [UIColor lightGrayColor];
+  self.textField.textColor = [BookmarkTextFieldCell textColorForEditing:NO];
   self.textField.clearButtonMode = UITextFieldViewModeWhileEditing;
   self.textField.textAlignment = NSTextAlignmentRight;
   [self.textField setContentHuggingPriority:UILayoutPriorityDefaultLow
@@ -153,6 +153,10 @@
   return self;
 }
 
++ (UIColor*)textColorForEditing:(BOOL)editing {
+  return editing ? [UIColor blackColor] : [UIColor lightGrayColor];
+}
+
 - (void)prepareForReuse {
   [super prepareForReuse];
   [self.textField resignFirstResponder];
diff --git a/ios/net/cookies/cookie_store_ios.h b/ios/net/cookies/cookie_store_ios.h
index 93db008..a242723 100644
--- a/ios/net/cookies/cookie_store_ios.h
+++ b/ios/net/cookies/cookie_store_ios.h
@@ -64,10 +64,6 @@
                  NetLog* net_log);
 
   // Used by ChromeSigninCookieManager/Cronet.
-  // TODO(crbug.com/801910): Remove this constructor once the internal
-  // chrome_signin_cookie_manager.mm is converted to using the one with NetLog.
-  explicit CookieStoreIOS(NSHTTPCookieStorage* ns_cookie_store);
-
   // TODO(crbug.com/759226): Remove once the migration to use SystemCookieStore
   // is finished.
   CookieStoreIOS(NSHTTPCookieStorage* ns_cookie_store, NetLog* net_log);
diff --git a/ios/net/cookies/cookie_store_ios.mm b/ios/net/cookies/cookie_store_ios.mm
index d13730d..72d25fd 100644
--- a/ios/net/cookies/cookie_store_ios.mm
+++ b/ios/net/cookies/cookie_store_ios.mm
@@ -229,10 +229,6 @@
                      std::move(system_cookie_store),
                      net_log) {}
 
-CookieStoreIOS::CookieStoreIOS(NSHTTPCookieStorage* ns_cookie_store)
-    : CookieStoreIOS(std::make_unique<NSHTTPSystemCookieStore>(ns_cookie_store),
-                     nullptr /* net_log */) {}
-
 CookieStoreIOS::CookieStoreIOS(NSHTTPCookieStorage* ns_cookie_store,
                                NetLog* net_log)
     : CookieStoreIOS(std::make_unique<NSHTTPSystemCookieStore>(ns_cookie_store),
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc
index 8598166..fa6a12c 100644
--- a/media/audio/audio_output_device.cc
+++ b/media/audio/audio_output_device.cc
@@ -182,7 +182,7 @@
   if (state_ == IDLE && !(did_receive_auth_.IsSignaled() && device_id_.empty()))
     RequestDeviceAuthorizationOnIOThread();
 
-  ipc_->CreateStream(this, audio_parameters_ /* TODO(ossu):, processing_id_ */);
+  ipc_->CreateStream(this, audio_parameters_, processing_id_);
   // By default, start playing right away.
   ipc_->PlayStream();
   state_ = STREAM_CREATION_REQUESTED;
diff --git a/media/audio/audio_output_device_unittest.cc b/media/audio/audio_output_device_unittest.cc
index f172c30..533f47e 100644
--- a/media/audio/audio_output_device_unittest.cc
+++ b/media/audio/audio_output_device_unittest.cc
@@ -77,9 +77,11 @@
                void(AudioOutputIPCDelegate* delegate,
                     int session_id,
                     const std::string& device_id));
-  MOCK_METHOD2(CreateStream,
-               void(AudioOutputIPCDelegate* delegate,
-                    const AudioParameters& params));
+  MOCK_METHOD3(
+      CreateStream,
+      void(AudioOutputIPCDelegate* delegate,
+           const AudioParameters& params,
+           const base::Optional<base::UnguessableToken>& processing_id));
   MOCK_METHOD0(PlayStream, void());
   MOCK_METHOD0(PauseStream, void());
   MOCK_METHOD0(CloseStream, void());
@@ -178,7 +180,7 @@
 
 void AudioOutputDeviceTest::StartAudioDevice() {
   if (device_status_ == OUTPUT_DEVICE_STATUS_OK)
-    EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _));
+    EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _, _));
   else
     EXPECT_CALL(callback_, OnRenderError());
 
@@ -389,7 +391,7 @@
   audio_device->Start();
   EXPECT_CALL(*ipc, RequestDeviceAuthorization(audio_device.get(), 0,
                                                kDefaultDeviceId));
-  EXPECT_CALL(*ipc, CreateStream(audio_device.get(), _));
+  EXPECT_CALL(*ipc, CreateStream(audio_device.get(), _, _));
   EXPECT_CALL(*ipc, PlayStream());
   task_env_.RunUntilIdle();
   Mock::VerifyAndClear(ipc);
@@ -450,7 +452,7 @@
   audio_device->Start();
   EXPECT_CALL(*ipc, RequestDeviceAuthorization(audio_device.get(), 0,
                                                kNonDefaultDeviceId));
-  EXPECT_CALL(*ipc, CreateStream(audio_device.get(), _));
+  EXPECT_CALL(*ipc, CreateStream(audio_device.get(), _, _));
   EXPECT_CALL(*ipc, PlayStream());
   task_env_.RunUntilIdle();
   Mock::VerifyAndClear(ipc);
@@ -486,7 +488,7 @@
   audio_device->Start();
   EXPECT_CALL(*ipc, RequestDeviceAuthorization(audio_device.get(), 0,
                                                kNonDefaultDeviceId));
-  EXPECT_CALL(*ipc, CreateStream(audio_device.get(), _));
+  EXPECT_CALL(*ipc, CreateStream(audio_device.get(), _, _));
   EXPECT_CALL(*ipc, PlayStream());
   task_env_.RunUntilIdle();
   Mock::VerifyAndClear(ipc);
diff --git a/media/audio/audio_output_ipc.h b/media/audio/audio_output_ipc.h
index d287ac0c..669a1c7 100644
--- a/media/audio/audio_output_ipc.h
+++ b/media/audio/audio_output_ipc.h
@@ -9,6 +9,7 @@
 
 #include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
+#include "base/unguessable_token.h"
 #include "media/base/audio_parameters.h"
 #include "media/base/media_export.h"
 #include "media/base/output_device_info.h"
@@ -81,8 +82,10 @@
   // the default device will be used.
   // Once the stream has been created, the implementation will notify
   // |delegate| by calling OnStreamCreated().
-  virtual void CreateStream(AudioOutputIPCDelegate* delegate,
-                            const AudioParameters& params) = 0;
+  virtual void CreateStream(
+      AudioOutputIPCDelegate* delegate,
+      const AudioParameters& params,
+      const base::Optional<base::UnguessableToken>& processing_id) = 0;
 
   // Starts playing the stream.  This should generate a call to
   // AudioOutputController::Play().
diff --git a/media/mojo/interfaces/audio_output_stream.mojom b/media/mojo/interfaces/audio_output_stream.mojom
index 3d901f5..9683e76 100644
--- a/media/mojo/interfaces/audio_output_stream.mojom
+++ b/media/mojo/interfaces/audio_output_stream.mojom
@@ -4,6 +4,7 @@
 
 module media.mojom;
 
+import "mojo/public/mojom/base/unguessable_token.mojom";
 import "media/mojo/interfaces/audio_data_pipe.mojom";
 import "media/mojo/interfaces/audio_parameters.mojom";
 import "media/mojo/interfaces/media_types.mojom";
@@ -68,9 +69,12 @@
   // Creates a new AudioOutputStream using |params|. |client| is notified when
   // the stream is ready. The stream lifetime is bound by the lifetime of
   // |client|. On error, the |client| will have a disconnect reason among the
-  // specified ones in AudioOutputStreamProviderClient.
+  // specified ones in AudioOutputStreamProviderClient. |processing_id|, if
+  // provided, identifies the group of input and output streams that are related
+  // during audio processing.
   // Can only be called once.
-  Acquire(AudioParameters params, AudioOutputStreamProviderClient client);
+  Acquire(AudioParameters params, AudioOutputStreamProviderClient client,
+          mojo_base.mojom.UnguessableToken? processing_id);
 };
 
 interface AudioOutputStreamProviderClient {
diff --git a/media/mojo/services/mojo_audio_output_stream_provider.cc b/media/mojo/services/mojo_audio_output_stream_provider.cc
index 1a661e80..fb15f4c 100644
--- a/media/mojo/services/mojo_audio_output_stream_provider.cc
+++ b/media/mojo/services/mojo_audio_output_stream_provider.cc
@@ -36,8 +36,12 @@
 
 void MojoAudioOutputStreamProvider::Acquire(
     const AudioParameters& params,
-    mojom::AudioOutputStreamProviderClientPtr provider_client) {
+    mojom::AudioOutputStreamProviderClientPtr provider_client,
+    const base::Optional<base::UnguessableToken>& processing_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+// |processing_id| gets dropped here. It's not supported outside of the audio
+// service. As this class is slated for removal, it will not be updated to
+// support audio processing.
 #if !defined(OS_ANDROID)
   if (params.IsBitstreamFormat()) {
     // Bitstream streams are only supported on Android.
diff --git a/media/mojo/services/mojo_audio_output_stream_provider.h b/media/mojo/services/mojo_audio_output_stream_provider.h
index 0d580f3..f3053bb 100644
--- a/media/mojo/services/mojo_audio_output_stream_provider.h
+++ b/media/mojo/services/mojo_audio_output_stream_provider.h
@@ -44,7 +44,8 @@
   // mojom::AudioOutputStreamProvider implementation.
   void Acquire(
       const AudioParameters& params,
-      mojom::AudioOutputStreamProviderClientPtr provider_client) override;
+      mojom::AudioOutputStreamProviderClientPtr provider_client,
+      const base::Optional<base::UnguessableToken>& processing_id) override;
 
   // Called when |audio_output_| had an error.
   void CleanUp(bool had_error);
diff --git a/media/mojo/services/mojo_audio_output_stream_provider_unittest.cc b/media/mojo/services/mojo_audio_output_stream_provider_unittest.cc
index c0e1dfe0..58e43c3 100644
--- a/media/mojo/services/mojo_audio_output_stream_provider_unittest.cc
+++ b/media/mojo/services/mojo_audio_output_stream_provider_unittest.cc
@@ -84,12 +84,12 @@
   mojom::AudioOutputStreamProviderClientPtr client_1;
   mojo::MakeRequest(&client_1);
   provider_ptr->Acquire(media::AudioParameters::UnavailableDeviceParams(),
-                        std::move(client_1));
+                        std::move(client_1), base::nullopt);
 
   mojom::AudioOutputStreamProviderClientPtr client_2;
   mojo::MakeRequest(&client_2);
   provider_ptr->Acquire(media::AudioParameters::UnavailableDeviceParams(),
-                        std::move(client_2));
+                        std::move(client_2), base::nullopt);
 
   EXPECT_CALL(deleter, Run(provider)).WillOnce(DeleteArg<0>());
   base::RunLoop().RunUntilIdle();
@@ -121,7 +121,7 @@
 
   mojom::AudioOutputStreamProviderClientPtr client;
   mojo::MakeRequest(&client);
-  provider_ptr->Acquire(params, std::move(client));
+  provider_ptr->Acquire(params, std::move(client), base::nullopt);
 
 #if defined(OS_ANDROID)
   base::RunLoop().RunUntilIdle();
diff --git a/services/audio/BUILD.gn b/services/audio/BUILD.gn
index 3374963..44d9eb1 100644
--- a/services/audio/BUILD.gn
+++ b/services/audio/BUILD.gn
@@ -77,6 +77,9 @@
     "snooper_node.h",
     "stream_factory.cc",
     "stream_factory.h",
+    "stream_monitor.h",
+    "stream_monitor_coordinator.cc",
+    "stream_monitor_coordinator.h",
     "sync_reader.cc",
     "sync_reader.h",
     "system_info.cc",
diff --git a/services/audio/output_controller.cc b/services/audio/output_controller.cc
index b2fdd651..a8a77a1 100644
--- a/services/audio/output_controller.cc
+++ b/services/audio/output_controller.cc
@@ -18,6 +18,7 @@
 #include "base/threading/platform_thread.h"
 #include "base/trace_event/trace_event.h"
 #include "media/base/audio_timestamp_helper.h"
+#include "services/audio/stream_monitor.h"
 
 using base::TimeDelta;
 
@@ -88,11 +89,14 @@
                         on_more_io_data_called_.IsOne());
 }
 
-OutputController::OutputController(media::AudioManager* audio_manager,
-                                   EventHandler* handler,
-                                   const media::AudioParameters& params,
-                                   const std::string& output_device_id,
-                                   SyncReader* sync_reader)
+OutputController::OutputController(
+    media::AudioManager* audio_manager,
+    EventHandler* handler,
+    const media::AudioParameters& params,
+    const std::string& output_device_id,
+    SyncReader* sync_reader,
+    StreamMonitorCoordinator* stream_monitor_coordinator,
+    const base::UnguessableToken& processing_id)
     : audio_manager_(audio_manager),
       params_(params),
       handler_(handler),
@@ -104,6 +108,8 @@
       volume_(1.0),
       state_(kEmpty),
       sync_reader_(sync_reader),
+      stream_monitor_coordinator_(stream_monitor_coordinator),
+      processing_id_(processing_id),
       power_monitor_(
           params.sample_rate(),
           TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)),
@@ -112,6 +118,7 @@
   DCHECK(handler_);
   DCHECK(sync_reader_);
   DCHECK(task_runner_.get());
+  DCHECK(stream_monitor_coordinator_ || processing_id.is_empty());
 }
 
 OutputController::~OutputController() {
@@ -179,6 +186,16 @@
   // Finally set the state to kCreated.
   state_ = kCreated;
 
+  if (processing_id_) {
+    // Ensure new monitors know that we're active.
+    stream_monitor_coordinator_->AddObserver(processing_id_, this);
+    // Ensure existing monitors do as well.
+    for (StreamMonitor* monitor :
+         stream_monitor_coordinator_->GetCurrentMembers(processing_id_)) {
+      monitor->OnStreamActive(this);
+    }
+  }
+
   return true;
 }
 
@@ -300,6 +317,15 @@
 
   sync_reader_->Read(dest);
 
+  const base::TimeTicks reference_time = delay_timestamp + delay;
+
+  {
+    base::AutoLock lock(realtime_snooper_lock_);
+    for (Snooper* snooper : realtime_snoopers_) {
+      snooper->OnData(*dest, reference_time, volume_);
+    }
+  }
+
   const int frames =
       dest->is_bitstream_format() ? dest->GetBitstreamFrames() : dest->frames();
   delay +=
@@ -308,7 +334,6 @@
   sync_reader_->RequestMoreData(delay, delay_timestamp, prior_frames_skipped);
 
   if (!should_duplicate_.IsZero()) {
-    const base::TimeTicks reference_time = delay_timestamp + delay;
     std::unique_ptr<media::AudioBus> copy(media::AudioBus::Create(params_));
     dest->CopyTo(copy.get());
     task_runner_->PostTask(
@@ -380,7 +405,18 @@
 
     // De-register from state change callbacks if stream_ was created via
     // AudioManager.
-      audio_manager_->RemoveOutputDeviceChangeListener(this);
+    audio_manager_->RemoveOutputDeviceChangeListener(this);
+
+    // Only notify and remove ourselves if startup was successful.
+    if (processing_id_ && state_ != kEmpty) {
+      // Don't send out activation messages for now.
+      stream_monitor_coordinator_->RemoveObserver(processing_id_, this);
+      // Ensure everyone monitoring us knows we're no-longer active.
+      for (StreamMonitor* monitor :
+           stream_monitor_coordinator_->GetCurrentMembers(processing_id_)) {
+        monitor->OnStreamInactive(this);
+      }
+    }
 
     StopStream();
     stream_->Close();
@@ -397,31 +433,47 @@
 }
 
 std::string OutputController::GetDeviceId() const {
-  // FIXME(ossu): Should this return "" or
-  // AudioDeviceDescription::kDefaultDeviceId for the default device.
-  return output_device_id_;
+  return output_device_id_.empty()
+             ? media::AudioDeviceDescription::kDefaultDeviceId
+             : output_device_id_;
 }
 
 void OutputController::StartSnooping(Snooper* snooper, SnoopingMode mode) {
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(snooper);
-  DCHECK_EQ(mode, SnoopingMode::kDeferred);
 
-  if (snoopers_.empty())
-    should_duplicate_.Increment();
-  DCHECK(!base::ContainsValue(snoopers_, snooper));
-  snoopers_.push_back(snooper);
+  if (mode == SnoopingMode::kDeferred) {
+    if (snoopers_.empty())
+      should_duplicate_.Increment();
+    DCHECK(!base::ContainsValue(snoopers_, snooper));
+    snoopers_.push_back(snooper);
+  } else {  // SnoopingMode::kRealtime
+    // The list will only update on this thread, but may be read from another.
+    DCHECK(!base::ContainsValue(realtime_snoopers_, snooper));
+    base::AutoLock lock(realtime_snooper_lock_);
+    realtime_snoopers_.push_back(snooper);
+  }
 }
 
 void OutputController::StopSnooping(Snooper* snooper, SnoopingMode mode) {
   DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK_EQ(mode, SnoopingMode::kDeferred);
 
-  const auto it = std::find(snoopers_.begin(), snoopers_.end(), snooper);
-  DCHECK(it != snoopers_.end());
-  snoopers_.erase(it);
-  if (snoopers_.empty())
-    should_duplicate_.Decrement();
+  if (mode == SnoopingMode::kDeferred) {
+    const auto it = std::find(snoopers_.begin(), snoopers_.end(), snooper);
+    DCHECK(it != snoopers_.end());
+    snoopers_.erase(it);
+    if (snoopers_.empty())
+      should_duplicate_.Decrement();
+  } else {  // SnoopingMode::kRealtime
+    // The list will only update on this thread, but may be read from another.
+    const auto it = std::find(realtime_snoopers_.begin(),
+                              realtime_snoopers_.end(), snooper);
+    DCHECK(it != realtime_snoopers_.end());
+    // We also don't care about ordering, so swap and pop rather than erase.
+    base::AutoLock lock(realtime_snooper_lock_);
+    *it = realtime_snoopers_.back();
+    realtime_snoopers_.pop_back();
+  }
 }
 
 void OutputController::StartMuting() {
@@ -450,6 +502,15 @@
     OnDeviceChange();
 }
 
+void OutputController::OnMemberJoinedGroup(StreamMonitor* monitor) {
+  // We're only observing the group when we're active.
+  monitor->OnStreamActive(this);
+}
+
+void OutputController::OnMemberLeftGroup(StreamMonitor* monitor) {
+  // Do nothing. The monitor will have already cleaned up.
+}
+
 void OutputController::OnDeviceChange() {
   DCHECK(task_runner_->BelongsToCurrentThread());
   SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.DeviceChangeTime");
diff --git a/services/audio/output_controller.h b/services/audio/output_controller.h
index dfb20ce..3589f132 100644
--- a/services/audio/output_controller.h
+++ b/services/audio/output_controller.h
@@ -27,6 +27,7 @@
 #include "media/audio/audio_power_monitor.h"
 #include "media/audio/audio_source_diverter.h"
 #include "services/audio/loopback_group_member.h"
+#include "services/audio/stream_monitor_coordinator.h"
 
 // An OutputController controls an AudioOutputStream and provides data to this
 // output stream. It executes audio operations like play, pause, stop, etc. on
@@ -61,7 +62,8 @@
 
 class OutputController : public media::AudioOutputStream::AudioSourceCallback,
                          public LoopbackGroupMember,
-                         public media::AudioManager::AudioDeviceListener {
+                         public media::AudioManager::AudioDeviceListener,
+                         public StreamMonitorCoordinator::Observer {
  public:
   // An event handler that receives events from the OutputController. The
   // following methods are called on the audio manager thread.
@@ -108,7 +110,9 @@
                    EventHandler* handler,
                    const media::AudioParameters& params,
                    const std::string& output_device_id,
-                   SyncReader* sync_reader);
+                   SyncReader* sync_reader,
+                   StreamMonitorCoordinator* stream_monitor_coordinator,
+                   const base::UnguessableToken& processing_id);
   ~OutputController() override;
 
   // Indicates whether audio power level analysis will be performed.  If false,
@@ -156,6 +160,10 @@
   void StartMuting() override;
   void StopMuting() override;
 
+  // StreamMonitorCoordinator::Observer implementation.
+  void OnMemberJoinedGroup(StreamMonitor* monitor) override;
+  void OnMemberLeftGroup(StreamMonitor* monitor) override;
+
   // AudioDeviceListener implementation.  When called OutputController will
   // shutdown the existing |stream_|, create a new stream, and then transition
   // back to an equivalent state prior to being called.
@@ -250,6 +258,9 @@
   std::vector<Snooper*> snoopers_;
   base::AtomicRefCount should_duplicate_;
 
+  base::Lock realtime_snooper_lock_;
+  std::vector<Snooper*> realtime_snoopers_;
+
   // The current volume of the audio stream.
   double volume_;
 
@@ -258,6 +269,9 @@
   // SyncReader is used only in low latency mode for synchronous reading.
   SyncReader* const sync_reader_;
 
+  StreamMonitorCoordinator* const stream_monitor_coordinator_;
+  base::UnguessableToken const processing_id_;
+
   // Scans audio samples from OnMoreData() as input to compute power levels.
   media::AudioPowerMonitor power_monitor_;
 
diff --git a/services/audio/output_controller_unittest.cc b/services/audio/output_controller_unittest.cc
index 16cffed..8b0ffee 100644
--- a/services/audio/output_controller_unittest.cc
+++ b/services/audio/output_controller_unittest.cc
@@ -97,6 +97,17 @@
   DISALLOW_COPY_AND_ASSIGN(MockOutputControllerSyncReader);
 };
 
+class MockStreamMonitor : public StreamMonitor {
+ public:
+  MockStreamMonitor() = default;
+
+  MOCK_METHOD1(OnStreamActive, void(Snoopable* snoopable));
+  MOCK_METHOD1(OnStreamInactive, void(Snoopable* snoopable));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockStreamMonitor);
+};
+
 // Wraps an AudioOutputStream instance, calling DidXYZ() mock methods for test
 // verification of controller behavior. If a null AudioOutputStream pointer is
 // provided to the constructor, a "data pump" thread will be run between the
@@ -308,14 +319,16 @@
 
 class OutputControllerTest : public ::testing::Test {
  public:
-  OutputControllerTest() : group_id_(base::UnguessableToken::Create()) {
-  }
+  OutputControllerTest()
+      : group_id_(base::UnguessableToken::Create()),
+        processing_id_(base::UnguessableToken::Create()) {}
 
   ~OutputControllerTest() override { audio_manager_.Shutdown(); }
 
   void SetUp() override {
     controller_.emplace(&audio_manager_, &mock_event_handler_, GetTestParams(),
-                        std::string(), &mock_sync_reader_);
+                        std::string(), &mock_sync_reader_,
+                        &stream_monitor_coordinator_, processing_id_);
     controller_->SetVolume(kTestVolume);
   }
 
@@ -402,8 +415,8 @@
     Mock::VerifyAndClearExpectations(&mock_event_handler_);
   }
 
-  void StartSnooping(MockSnooper* snooper) {
-    controller_->StartSnooping(snooper, Snoopable::SnoopingMode::kDeferred);
+  void StartSnooping(MockSnooper* snooper, Snoopable::SnoopingMode mode) {
+    controller_->StartSnooping(snooper, mode);
   }
 
   void WaitForSnoopedData(MockSnooper* snooper) {
@@ -415,8 +428,18 @@
     Mock::VerifyAndClearExpectations(snooper);
   }
 
-  void StopSnooping(MockSnooper* snooper) {
-    controller_->StopSnooping(snooper, Snoopable::SnoopingMode::kDeferred);
+  void StopSnooping(MockSnooper* snooper, Snoopable::SnoopingMode mode) {
+    controller_->StopSnooping(snooper, mode);
+  }
+
+  Snoopable* GetSnoopable() { return &(*controller_); }
+
+  void JoinProcessingGroup(StreamMonitor* monitor) {
+    stream_monitor_coordinator_.RegisterMember(processing_id_, monitor);
+  }
+
+  void LeaveProcessingGroup(StreamMonitor* monitor) {
+    stream_monitor_coordinator_.UnregisterMember(processing_id_, monitor);
   }
 
   void Close() {
@@ -458,9 +481,11 @@
   base::TestMessageLoop message_loop_;
   AudioManagerForControllerTest audio_manager_;
   base::UnguessableToken group_id_;
+  base::UnguessableToken processing_id_;
   StrictMock<MockOutputControllerEventHandler> mock_event_handler_;
   StrictMock<MockOutputControllerSyncReader> mock_sync_reader_;
   base::Optional<OutputController> controller_;
+  StreamMonitorCoordinator stream_monitor_coordinator_;
 
   DISALLOW_COPY_AND_ASSIGN(OutputControllerTest);
 };
@@ -584,68 +609,72 @@
   EXPECT_EQ(playout_stream, last_closed_stream());
 }
 
-TEST_F(OutputControllerTest, SnoopCreatePlayStopClose) {
+class WithSnoopingMode
+    : public OutputControllerTest,
+      public ::testing::WithParamInterface<Snoopable::SnoopingMode> {};
+
+TEST_P(WithSnoopingMode, SnoopCreatePlayStopClose) {
   NiceMock<MockSnooper> snooper;
-  StartSnooping(&snooper);
+  StartSnooping(&snooper, GetParam());
   Create();
   Play();
   WaitForSnoopedData(&snooper);
-  StopSnooping(&snooper);
+  StopSnooping(&snooper, GetParam());
   Close();
 }
 
-TEST_F(OutputControllerTest, CreatePlaySnoopStopClose) {
+TEST_P(WithSnoopingMode, CreatePlaySnoopStopClose) {
   NiceMock<MockSnooper> snooper;
   Create();
   Play();
-  StartSnooping(&snooper);
+  StartSnooping(&snooper, GetParam());
   WaitForSnoopedData(&snooper);
-  StopSnooping(&snooper);
+  StopSnooping(&snooper, GetParam());
   Close();
 }
 
-TEST_F(OutputControllerTest, CreatePlaySnoopCloseStop) {
+TEST_P(WithSnoopingMode, CreatePlaySnoopCloseStop) {
   NiceMock<MockSnooper> snooper;
   Create();
   Play();
-  StartSnooping(&snooper);
+  StartSnooping(&snooper, GetParam());
   WaitForSnoopedData(&snooper);
   Close();
-  StopSnooping(&snooper);
+  StopSnooping(&snooper, GetParam());
 }
 
-TEST_F(OutputControllerTest, TwoSnoopers_StartAtDifferentTimes) {
+TEST_P(WithSnoopingMode, TwoSnoopers_StartAtDifferentTimes) {
   NiceMock<MockSnooper> snooper1;
   NiceMock<MockSnooper> snooper2;
-  StartSnooping(&snooper1);
+  StartSnooping(&snooper1, GetParam());
   Create();
   Play();
   WaitForSnoopedData(&snooper1);
-  StartSnooping(&snooper2);
+  StartSnooping(&snooper2, GetParam());
   WaitForSnoopedData(&snooper2);
   WaitForSnoopedData(&snooper1);
   WaitForSnoopedData(&snooper2);
   Close();
-  StopSnooping(&snooper1);
-  StopSnooping(&snooper2);
+  StopSnooping(&snooper1, GetParam());
+  StopSnooping(&snooper2, GetParam());
 }
 
-TEST_F(OutputControllerTest, TwoSnoopers_StopAtDifferentTimes) {
+TEST_P(WithSnoopingMode, TwoSnoopers_StopAtDifferentTimes) {
   NiceMock<MockSnooper> snooper1;
   NiceMock<MockSnooper> snooper2;
   Create();
   Play();
-  StartSnooping(&snooper1);
+  StartSnooping(&snooper1, GetParam());
   WaitForSnoopedData(&snooper1);
-  StartSnooping(&snooper2);
+  StartSnooping(&snooper2, GetParam());
   WaitForSnoopedData(&snooper2);
-  StopSnooping(&snooper1);
+  StopSnooping(&snooper1, GetParam());
   WaitForSnoopedData(&snooper2);
   Close();
-  StopSnooping(&snooper2);
+  StopSnooping(&snooper2, GetParam());
 }
 
-TEST_F(OutputControllerTest, SnoopWhileMuting) {
+TEST_P(WithSnoopingMode, SnoopWhileMuting) {
   NiceMock<MockSnooper> snooper;
 
   StartMutingBeforePlaying();
@@ -662,13 +691,13 @@
   EXPECT_EQ(nullptr, last_closed_stream());
   EXPECT_EQ(AudioParameters::AUDIO_FAKE, mute_stream->format());
 
-  StartSnooping(&snooper);
+  StartSnooping(&snooper, GetParam());
   ASSERT_EQ(mute_stream, last_created_stream());
   EXPECT_EQ(nullptr, last_closed_stream());
   EXPECT_EQ(AudioParameters::AUDIO_FAKE, mute_stream->format());
   WaitForSnoopedData(&snooper);
 
-  StopSnooping(&snooper);
+  StopSnooping(&snooper, GetParam());
   ASSERT_EQ(mute_stream, last_created_stream());
   EXPECT_EQ(nullptr, last_closed_stream());
   EXPECT_EQ(AudioParameters::AUDIO_FAKE, mute_stream->format());
@@ -678,5 +707,44 @@
   EXPECT_EQ(mute_stream, last_closed_stream());
 }
 
+INSTANTIATE_TEST_CASE_P(OutputControllerSnoopingTest,
+                        WithSnoopingMode,
+                        ::testing::Values(Snoopable::SnoopingMode::kDeferred,
+                                          Snoopable::SnoopingMode::kRealtime));
+
+TEST_F(OutputControllerTest, InformsStreamMonitorsAlreadyInGroup) {
+  MockStreamMonitor monitor;
+  EXPECT_CALL(monitor, OnStreamActive(GetSnoopable()));
+  EXPECT_CALL(monitor, OnStreamInactive(GetSnoopable()));
+  JoinProcessingGroup(&monitor);
+  Create();
+  Play();
+  Close();
+  LeaveProcessingGroup(&monitor);
+}
+
+TEST_F(OutputControllerTest, InformsStreamMonitorsJoiningInGroup) {
+  MockStreamMonitor monitor;
+  EXPECT_CALL(monitor, OnStreamActive(GetSnoopable()));
+  EXPECT_CALL(monitor, OnStreamInactive(GetSnoopable()));
+  Create();
+  Play();
+  JoinProcessingGroup(&monitor);
+  Close();
+  LeaveProcessingGroup(&monitor);
+}
+
+TEST_F(OutputControllerTest,
+       DoesNotInformStreamMonitorsJoiningInGroupAfterClose) {
+  MockStreamMonitor monitor;
+  EXPECT_CALL(monitor, OnStreamActive(GetSnoopable())).Times(0);
+  EXPECT_CALL(monitor, OnStreamInactive(GetSnoopable())).Times(0);
+  Create();
+  Play();
+  Close();
+  JoinProcessingGroup(&monitor);
+  LeaveProcessingGroup(&monitor);
+}
+
 }  // namespace
 }  // namespace audio
diff --git a/services/audio/output_stream.cc b/services/audio/output_stream.cc
index 7536c21..602f0d5b 100644
--- a/services/audio/output_stream.cc
+++ b/services/audio/output_stream.cc
@@ -28,7 +28,9 @@
     const std::string& output_device_id,
     const media::AudioParameters& params,
     LoopbackCoordinator* coordinator,
-    const base::UnguessableToken& loopback_group_id)
+    const base::UnguessableToken& loopback_group_id,
+    StreamMonitorCoordinator* stream_monitor_coordinator,
+    const base::UnguessableToken& processing_id)
     : foreign_socket_(),
       delete_callback_(std::move(delete_callback)),
       binding_(this, std::move(stream_request)),
@@ -42,7 +44,13 @@
                    : base::DoNothing(),
               params,
               &foreign_socket_),
-      controller_(audio_manager, this, params, output_device_id, &reader_),
+      controller_(audio_manager,
+                  this,
+                  params,
+                  output_device_id,
+                  &reader_,
+                  stream_monitor_coordinator,
+                  processing_id),
       loopback_group_id_(loopback_group_id),
       weak_factory_(this) {
   DCHECK(binding_.is_bound());
diff --git a/services/audio/output_stream.h b/services/audio/output_stream.h
index 9af7a9d..bf859172 100644
--- a/services/audio/output_stream.h
+++ b/services/audio/output_stream.h
@@ -24,6 +24,7 @@
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "services/audio/loopback_coordinator.h"
 #include "services/audio/output_controller.h"
+#include "services/audio/stream_monitor_coordinator.h"
 #include "services/audio/sync_reader.h"
 
 namespace base {
@@ -53,7 +54,9 @@
                const std::string& output_device_id,
                const media::AudioParameters& params,
                LoopbackCoordinator* coordinator,
-               const base::UnguessableToken& loopback_group_id);
+               const base::UnguessableToken& loopback_group_id,
+               StreamMonitorCoordinator* stream_monitor_coordinator,
+               const base::UnguessableToken& processing_id);
 
   ~OutputStream() final;
 
diff --git a/services/audio/output_stream_unittest.cc b/services/audio/output_stream_unittest.cc
index 1695704..f5348fd1 100644
--- a/services/audio/output_stream_unittest.cc
+++ b/services/audio/output_stream_unittest.cc
@@ -133,7 +133,8 @@
     stream_factory_ptr_->CreateOutputStream(
         mojo::MakeRequest(&stream_ptr), observer_.MakePtrInfo(), log_.MakePtr(),
         "", media::AudioParameters::UnavailableDeviceParams(),
-        base::UnguessableToken::Create(), created_callback_.Get());
+        base::UnguessableToken::Create(), base::nullopt,
+        created_callback_.Get());
     return stream_ptr;
   }
 
@@ -142,7 +143,8 @@
     stream_factory_ptr_->CreateOutputStream(
         mojo::MakeRequest(&stream_ptr), nullptr, log_.MakePtr(), "",
         media::AudioParameters::UnavailableDeviceParams(),
-        base::UnguessableToken::Create(), created_callback_.Get());
+        base::UnguessableToken::Create(), base::nullopt,
+        created_callback_.Get());
     return stream_ptr;
   }
 
@@ -151,7 +153,8 @@
     stream_factory_ptr_->CreateOutputStream(
         mojo::MakeRequest(&stream_ptr), observer_.MakePtrInfo(), nullptr, "",
         media::AudioParameters::UnavailableDeviceParams(),
-        base::UnguessableToken::Create(), created_callback_.Get());
+        base::UnguessableToken::Create(), base::nullopt,
+        created_callback_.Get());
     return stream_ptr;
   }
 
diff --git a/services/audio/public/cpp/fake_stream_factory.h b/services/audio/public/cpp/fake_stream_factory.h
index 8672b77..38ef657 100644
--- a/services/audio/public/cpp/fake_stream_factory.h
+++ b/services/audio/public/cpp/fake_stream_factory.h
@@ -48,6 +48,7 @@
       const std::string& output_device_id,
       const media::AudioParameters& params,
       const base::UnguessableToken& group_id,
+      const base::Optional<base::UnguessableToken>& processing_id,
       CreateOutputStreamCallback created_callback) override {}
   void BindMuter(mojom::LocalMuterAssociatedRequest request,
                  const base::UnguessableToken& group_id) override {}
@@ -61,8 +62,15 @@
       CreateLoopbackStreamCallback created_callback) override {}
 
   mojo::Binding<mojom::StreamFactory> binding_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
 };
 
+static_assert(
+    !std::is_abstract<FakeStreamFactory>(),
+    "FakeStreamFactory should implement all of the StreamFactory interface.");
+
 }  // namespace audio
 
 #endif  // SERVICES_AUDIO_PUBLIC_CPP_FAKE_STREAM_FACTORY_H_
diff --git a/services/audio/public/cpp/input_ipc_unittest.cc b/services/audio/public/cpp/input_ipc_unittest.cc
index 60568bb..815701d4 100644
--- a/services/audio/public/cpp/input_ipc_unittest.cc
+++ b/services/audio/public/cpp/input_ipc_unittest.cc
@@ -12,6 +12,7 @@
 #include "mojo/public/cpp/system/buffer.h"
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "services/audio/public/cpp/device_factory.h"
+#include "services/audio/public/cpp/fake_stream_factory.h"
 #include "services/audio/public/mojom/constants.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -33,10 +34,10 @@
   MOCK_METHOD1(SetVolume, void(double));
 };
 
-class FakeStreamFactory : public audio::mojom::StreamFactory {
+class TestStreamFactory : public audio::FakeStreamFactory {
  public:
-  FakeStreamFactory() : binding_(this), stream_(), stream_binding_(&stream_) {}
-  ~FakeStreamFactory() override = default;
+  TestStreamFactory() : stream_(), stream_binding_(&stream_) {}
+  ~TestStreamFactory() override = default;
   void CreateInputStream(media::mojom::AudioInputStreamRequest stream_request,
                          media::mojom::AudioInputStreamClientPtr client,
                          media::mojom::AudioInputStreamObserverPtr observer,
@@ -74,34 +75,10 @@
                void(const base::UnguessableToken& input_stream_id,
                     const std::string& output_device_id));
 
-  MOCK_METHOD7(CreateOutputStream,
-               void(media::mojom::AudioOutputStreamRequest stream_request,
-                    media::mojom::AudioOutputStreamObserverAssociatedPtrInfo
-                        observer_info,
-                    media::mojom::AudioLogPtr log,
-                    const std::string& output_device_id,
-                    const media::AudioParameters& params,
-                    const base::UnguessableToken& group_id,
-                    CreateOutputStreamCallback created_callback));
-
-  MOCK_METHOD2(BindMuter,
-               void(mojom::LocalMuterAssociatedRequest request,
-                    const base::UnguessableToken& group_id));
-
-  MOCK_METHOD7(CreateLoopbackStream,
-               void(media::mojom::AudioInputStreamRequest stream_request,
-                    media::mojom::AudioInputStreamClientPtr client,
-                    media::mojom::AudioInputStreamObserverPtr observer,
-                    const media::AudioParameters& params,
-                    uint32_t shared_memory_count,
-                    const base::UnguessableToken& group_id,
-                    CreateLoopbackStreamCallback created_callback));
-
   void Bind(mojo::ScopedMessagePipeHandle handle) {
     binding_.Bind(audio::mojom::StreamFactoryRequest(std::move(handle)));
   }
 
-  mojo::Binding<audio::mojom::StreamFactory> binding_;
   StrictMock<MockStream> stream_;
   media::mojom::AudioInputStreamClientPtr client_;
   mojo::Binding<media::mojom::AudioInputStream> stream_binding_;
@@ -142,21 +119,21 @@
       : scoped_task_environment(
             base::test::ScopedTaskEnvironment::MainThreadType::DEFAULT,
             base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED) {}
-  std::unique_ptr<StrictMock<FakeStreamFactory>> factory_;
+  std::unique_ptr<StrictMock<TestStreamFactory>> factory_;
 
   void SetUp() override {
     service_manager::mojom::ConnectorRequest request;
     std::unique_ptr<service_manager::Connector> connector =
         service_manager::Connector::Create(&request);
 
-    factory_ = std::make_unique<StrictMock<FakeStreamFactory>>();
+    factory_ = std::make_unique<StrictMock<TestStreamFactory>>();
     {
       service_manager::Connector::TestApi test_api(connector.get());
 
       test_api.OverrideBinderForTesting(
           service_manager::Identity(audio::mojom::kServiceName),
           audio::mojom::StreamFactory::Name_,
-          base::BindRepeating(&FakeStreamFactory::Bind,
+          base::BindRepeating(&TestStreamFactory::Bind,
                               base::Unretained(factory_.get())));
     }
     ipc = std::make_unique<InputIPC>(std::move(connector), kDeviceId, nullptr);
diff --git a/services/audio/public/cpp/output_device.cc b/services/audio/public/cpp/output_device.cc
index 70af78f..3ccc6e9 100644
--- a/services/audio/public/cpp/output_device.cc
+++ b/services/audio/public/cpp/output_device.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/optional.h"
 #include "base/threading/thread_restrictions.h"
 #include "media/audio/audio_output_device_thread_callback.h"
 #include "mojo/public/cpp/system/platform_handle.h"
@@ -32,7 +33,7 @@
       &OutputDevice::OnConnectionError, weak_factory_.GetWeakPtr()));
   stream_factory_->CreateOutputStream(
       std::move(stream_request), nullptr, nullptr, device_id, params,
-      base::UnguessableToken::Create(),
+      base::UnguessableToken::Create(), base::nullopt,
       base::BindOnce(&OutputDevice::StreamCreated, weak_factory_.GetWeakPtr()));
 }
 
diff --git a/services/audio/public/cpp/output_device_unittest.cc b/services/audio/public/cpp/output_device_unittest.cc
index a411fae4..258fd47a 100644
--- a/services/audio/public/cpp/output_device_unittest.cc
+++ b/services/audio/public/cpp/output_device_unittest.cc
@@ -75,6 +75,7 @@
       const std::string& output_device_id,
       const media::AudioParameters& params,
       const base::UnguessableToken& group_id,
+      const base::Optional<base::UnguessableToken>& processing_id,
       CreateOutputStreamCallback created_callback) final {
     EXPECT_FALSE(observer_info);
     EXPECT_FALSE(log);
diff --git a/services/audio/public/mojom/stream_factory.mojom b/services/audio/public/mojom/stream_factory.mojom
index b8ea767d..ea7bc73b 100644
--- a/services/audio/public/mojom/stream_factory.mojom
+++ b/services/audio/public/mojom/stream_factory.mojom
@@ -62,13 +62,16 @@
   // from. |data_pipe| is null in case stream creation failed. |device_id| is
   // either the |unique_id| field from an AudioDeviceDescription obtained from
   // the audio.mojom.SystemInfo interface, or "default". The stream |group_id|
-  // will later be used for muting streams or capturing them for loopback.
+  // is used for muting streams or capturing them for loopback. |processing_id|
+  // is used to connect the stream to input streams that need to analyze the
+  // output signal as part of their processing.
   CreateOutputStream(
     media.mojom.AudioOutputStream& stream,
     associated media.mojom.AudioOutputStreamObserver? observer,
     media.mojom.AudioLog? log,
     string device_id, media.mojom.AudioParameters params,
-    mojo_base.mojom.UnguessableToken group_id)
+    mojo_base.mojom.UnguessableToken group_id,
+    mojo_base.mojom.UnguessableToken? processing_id)
     => (media.mojom.ReadWriteAudioDataPipe? data_pipe);
 
   // Binds the request to the LocalMuter associated with the given |group_id|.
diff --git a/services/audio/stream_factory.cc b/services/audio/stream_factory.cc
index 45a9024..dcd39b6d 100644
--- a/services/audio/stream_factory.cc
+++ b/services/audio/stream_factory.cc
@@ -76,6 +76,7 @@
     const std::string& output_device_id,
     const media::AudioParameters& params,
     const base::UnguessableToken& group_id,
+    const base::Optional<base::UnguessableToken>& processing_id,
     CreateOutputStreamCallback created_callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
   TRACE_EVENT_NESTABLE_ASYNC_INSTANT1(
@@ -93,7 +94,9 @@
   output_streams_.insert(std::make_unique<OutputStream>(
       std::move(created_callback), std::move(deleter_callback),
       std::move(stream_request), std::move(observer), std::move(log),
-      audio_manager_, output_device_id, params, &coordinator_, group_id));
+      audio_manager_, output_device_id, params, &coordinator_, group_id,
+      &stream_monitor_coordinator_,
+      processing_id.value_or(base::UnguessableToken())));
 }
 
 void StreamFactory::BindMuter(mojom::LocalMuterAssociatedRequest request,
diff --git a/services/audio/stream_factory.h b/services/audio/stream_factory.h
index 14ab16f8..7c5629e 100644
--- a/services/audio/stream_factory.h
+++ b/services/audio/stream_factory.h
@@ -19,6 +19,7 @@
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "services/audio/loopback_coordinator.h"
 #include "services/audio/public/mojom/stream_factory.mojom.h"
+#include "services/audio/stream_monitor_coordinator.h"
 #include "services/audio/traced_service_ref.h"
 
 namespace base {
@@ -71,6 +72,7 @@
       const std::string& output_device_id,
       const media::AudioParameters& params,
       const base::UnguessableToken& group_id,
+      const base::Optional<base::UnguessableToken>& processing_id,
       CreateOutputStreamCallback created_callback) final;
   void BindMuter(mojom::LocalMuterAssociatedRequest request,
                  const base::UnguessableToken& group_id) final;
@@ -104,6 +106,7 @@
   LoopbackCoordinator coordinator_;
   std::vector<std::unique_ptr<LocalMuter>> muters_;
   std::vector<std::unique_ptr<LoopbackStream>> loopback_streams_;
+  StreamMonitorCoordinator stream_monitor_coordinator_;
   InputStreamSet input_streams_;
   OutputStreamSet output_streams_;
 
diff --git a/services/audio/stream_monitor.h b/services/audio/stream_monitor.h
new file mode 100644
index 0000000..2c698638
--- /dev/null
+++ b/services/audio/stream_monitor.h
@@ -0,0 +1,26 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_AUDIO_STREAM_MONITOR_H_
+#define SERVICES_AUDIO_STREAM_MONITOR_H_
+
+#include "base/unguessable_token.h"
+
+namespace audio {
+
+class Snoopable;
+
+class StreamMonitor {
+ public:
+  // Called when a stream in the group becomes active.
+  virtual void OnStreamActive(Snoopable* snoopable) = 0;
+  // Called when a stream in the group becomes inactive.
+  virtual void OnStreamInactive(Snoopable* snoopable) = 0;
+
+ protected:
+  virtual ~StreamMonitor() = default;
+};
+}  // namespace audio
+
+#endif  // SERVICES_AUDIO_STREAM_MONITOR_H_
diff --git a/services/audio/stream_monitor_coordinator.cc b/services/audio/stream_monitor_coordinator.cc
new file mode 100644
index 0000000..dd3b0f3
--- /dev/null
+++ b/services/audio/stream_monitor_coordinator.cc
@@ -0,0 +1,10 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/audio/stream_monitor_coordinator.h"
+#include "services/audio/group_coordinator-impl.h"
+
+namespace audio {
+template class GroupCoordinator<StreamMonitor>;
+}  // namespace audio
diff --git a/services/audio/stream_monitor_coordinator.h b/services/audio/stream_monitor_coordinator.h
new file mode 100644
index 0000000..c9889a7
--- /dev/null
+++ b/services/audio/stream_monitor_coordinator.h
@@ -0,0 +1,15 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_AUDIO_STREAM_MONITOR_COORDINATOR_H_
+#define SERVICES_AUDIO_STREAM_MONITOR_COORDINATOR_H_
+
+#include "services/audio/group_coordinator.h"
+#include "services/audio/stream_monitor.h"
+
+namespace audio {
+using StreamMonitorCoordinator = GroupCoordinator<StreamMonitor>;
+}  // namespace audio
+
+#endif  // SERVICES_AUDIO_STREAM_MONITOR_COORDINATOR_H_
diff --git a/services/audio/test/fake_loopback_group_member.cc b/services/audio/test/fake_loopback_group_member.cc
index ee43f1cc..64352ec 100644
--- a/services/audio/test/fake_loopback_group_member.cc
+++ b/services/audio/test/fake_loopback_group_member.cc
@@ -6,8 +6,10 @@
 
 #include <algorithm>
 #include <cmath>
+#include <string>
 
 #include "base/numerics/math_constants.h"
+#include "media/audio/audio_device_description.h"
 #include "media/base/audio_bus.h"
 
 namespace audio {
@@ -54,8 +56,7 @@
 }
 
 std::string FakeLoopbackGroupMember::GetDeviceId() const {
-  // FIXME(ossu): Provide a device ID or return default!
-  return "";
+  return media::AudioDeviceDescription::kDefaultDeviceId;
 }
 
 void FakeLoopbackGroupMember::StartSnooping(Snooper* snooper,
diff --git a/services/metrics/public/cpp/delegating_ukm_recorder.cc b/services/metrics/public/cpp/delegating_ukm_recorder.cc
index 370475a0..bad4cea0 100644
--- a/services/metrics/public/cpp/delegating_ukm_recorder.cc
+++ b/services/metrics/public/cpp/delegating_ukm_recorder.cc
@@ -44,16 +44,24 @@
         << "UpdateSourceURL invoked for NAVIGATION_ID or APP_ID SourceId";
     return;
   }
-  UpdateSourceURLImpl(source_id, url);
+
+  base::AutoLock auto_lock(lock_);
+  for (auto& iterator : delegates_)
+    iterator.second.UpdateSourceURL(source_id, url);
 }
 
-void DelegatingUkmRecorder::UpdateNavigationURL(SourceId source_id,
-                                                const GURL& url) {
+void DelegatingUkmRecorder::RecordNavigation(
+    SourceId source_id,
+    const UkmSource::NavigationData& navigation_data) {
   if (GetSourceIdType(source_id) != SourceIdType::NAVIGATION_ID) {
     DLOG(FATAL) << "UpdateNavigationURL invoked for non-NAVIGATION_ID SourceId";
     return;
   }
-  UpdateSourceURLImpl(source_id, url);
+
+  base::AutoLock auto_lock(lock_);
+  for (auto& iterator : delegates_) {
+    iterator.second.RecordNavigation(source_id, navigation_data);
+  }
 }
 
 void DelegatingUkmRecorder::UpdateAppURL(SourceId source_id, const GURL& url) {
@@ -66,13 +74,6 @@
     iterator.second.UpdateAppURL(source_id, url);
 }
 
-void DelegatingUkmRecorder::UpdateSourceURLImpl(SourceId source_id,
-                                                const GURL& url) {
-  base::AutoLock auto_lock(lock_);
-  for (auto& iterator : delegates_)
-    iterator.second.UpdateSourceURL(source_id, url);
-}
-
 void DelegatingUkmRecorder::AddEntry(mojom::UkmEntryPtr entry) {
   base::AutoLock auto_lock(lock_);
   // If there is exactly one delegate, just forward the call.
@@ -116,6 +117,18 @@
                                                    ptr_, source_id, url));
 }
 
+void DelegatingUkmRecorder::Delegate::RecordNavigation(
+    ukm::SourceId source_id,
+    const UkmSource::NavigationData& navigation_data) {
+  if (task_runner_->RunsTasksInCurrentSequence()) {
+    ptr_->RecordNavigation(source_id, navigation_data);
+    return;
+  }
+  task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&UkmRecorder::RecordNavigation, ptr_, source_id,
+                                navigation_data));
+}
+
 void DelegatingUkmRecorder::Delegate::AddEntry(mojom::UkmEntryPtr entry) {
   if (task_runner_->RunsTasksInCurrentSequence()) {
     ptr_->AddEntry(std::move(entry));
diff --git a/services/metrics/public/cpp/delegating_ukm_recorder.h b/services/metrics/public/cpp/delegating_ukm_recorder.h
index 8329bdc7..7bec6e8 100644
--- a/services/metrics/public/cpp/delegating_ukm_recorder.h
+++ b/services/metrics/public/cpp/delegating_ukm_recorder.h
@@ -50,15 +50,11 @@
   // UkmRecorder:
   void UpdateSourceURL(SourceId source_id, const GURL& url) override;
   void UpdateAppURL(SourceId source_id, const GURL& url) override;
+  void RecordNavigation(
+      SourceId source_id,
+      const UkmSource::NavigationData& navigation_data) override;
   void AddEntry(mojom::UkmEntryPtr entry) override;
 
-  void UpdateSourceURLImpl(SourceId source_id, const GURL& url);
-
-  // UpdateNavigationURL provides a variation of the UpdateSourceURL API for
-  // recording NAVIGATION_ID sources. This method should only be called by
-  // SourceUrlRecorderWebContentsObserver.
-  void UpdateNavigationURL(SourceId source_id, const GURL& url);
-
   class Delegate final {
    public:
     Delegate(scoped_refptr<base::SequencedTaskRunner> task_runner,
@@ -68,6 +64,8 @@
 
     void UpdateSourceURL(SourceId source_id, const GURL& url);
     void UpdateAppURL(SourceId source_id, const GURL& url);
+    void RecordNavigation(SourceId source_id,
+                          const UkmSource::NavigationData& navigation_data);
     void AddEntry(mojom::UkmEntryPtr entry);
 
    private:
diff --git a/services/metrics/public/cpp/mojo_ukm_recorder.cc b/services/metrics/public/cpp/mojo_ukm_recorder.cc
index cd00d49..164729e 100644
--- a/services/metrics/public/cpp/mojo_ukm_recorder.cc
+++ b/services/metrics/public/cpp/mojo_ukm_recorder.cc
@@ -37,6 +37,12 @@
   NOTREACHED();
 }
 
+void MojoUkmRecorder::RecordNavigation(
+    SourceId source_id,
+    const UkmSource::NavigationData& navigation_data) {
+  NOTREACHED();
+}
+
 void MojoUkmRecorder::AddEntry(mojom::UkmEntryPtr entry) {
   interface_->AddEntry(std::move(entry));
 }
diff --git a/services/metrics/public/cpp/mojo_ukm_recorder.h b/services/metrics/public/cpp/mojo_ukm_recorder.h
index 3cfcb37..5b34e84 100644
--- a/services/metrics/public/cpp/mojo_ukm_recorder.h
+++ b/services/metrics/public/cpp/mojo_ukm_recorder.h
@@ -45,6 +45,9 @@
   // UkmRecorder:
   void UpdateSourceURL(SourceId source_id, const GURL& url) override;
   void UpdateAppURL(SourceId source_id, const GURL& url) override;
+  void RecordNavigation(
+      SourceId source_id,
+      const UkmSource::NavigationData& navigation_data) override;
   void AddEntry(mojom::UkmEntryPtr entry) override;
 
   mojom::UkmRecorderInterfacePtr interface_;
diff --git a/services/metrics/public/cpp/ukm_recorder.h b/services/metrics/public/cpp/ukm_recorder.h
index 3aa02cf..e974ff9 100644
--- a/services/metrics/public/cpp/ukm_recorder.h
+++ b/services/metrics/public/cpp/ukm_recorder.h
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
 #include "services/metrics/public/cpp/metrics_export.h"
+#include "services/metrics/public/cpp/ukm_source.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
 #include "services/metrics/public/mojom/ukm_interface.mojom.h"
 #include "url/gurl.h"
@@ -132,6 +133,13 @@
   // should only be called by AppSourceUrlRecorder and DelegatingUkmRecorder.
   virtual void UpdateAppURL(SourceId source_id, const GURL& url) = 0;
 
+  // Associates navigation data with the UkmSource keyed by |source_id|. This
+  // should only be called by SourceUrlRecorderWebContentsObserver, for
+  // navigation sources.
+  virtual void RecordNavigation(
+      SourceId source_id,
+      const UkmSource::NavigationData& navigation_data) = 0;
+
   DISALLOW_COPY_AND_ASSIGN(UkmRecorder);
 };
 
diff --git a/services/metrics/public/cpp/ukm_source.cc b/services/metrics/public/cpp/ukm_source.cc
index ff856778..bb73e7bc 100644
--- a/services/metrics/public/cpp/ukm_source.cc
+++ b/services/metrics/public/cpp/ukm_source.cc
@@ -39,28 +39,49 @@
   g_custom_tab_state = visible ? kCustomTabTrue : kCustomTabFalse;
 }
 
+UkmSource::NavigationData UkmSource::NavigationData::CopyWithSanitizedUrls(
+    std::vector<GURL> sanitized_urls) const {
+  DCHECK_LE(sanitized_urls.size(), 2u);
+  DCHECK(!sanitized_urls.empty());
+
+  NavigationData sanitized_navigation_data;
+
+  // TODO(csharrison): Migrate this class to internally keep a vector<GURL>
+  // rather than two separate members.
+  sanitized_navigation_data.url = sanitized_urls.back();
+  if (sanitized_urls.size() == 2u)
+    sanitized_navigation_data.initial_url = sanitized_urls.front();
+
+  sanitized_navigation_data.previous_source_id = previous_source_id;
+  sanitized_navigation_data.opener_source_id = opener_source_id;
+  sanitized_navigation_data.tab_id = tab_id;
+  return sanitized_navigation_data;
+}
+
 UkmSource::UkmSource(ukm::SourceId id, const GURL& url)
     : id_(id),
-      url_(url),
       custom_tab_state_(g_custom_tab_state),
       creation_time_(base::TimeTicks::Now()) {
-  DCHECK(!url_.is_empty());
+  navigation_data_.url = url;
+  DCHECK(!url.is_empty());
+}
+
+UkmSource::UkmSource(ukm::SourceId id, const NavigationData& navigation_data)
+    : id_(id),
+      navigation_data_(navigation_data),
+      custom_tab_state_(g_custom_tab_state),
+      creation_time_(base::TimeTicks::Now()) {
+  DCHECK(GetSourceIdType(id_) == SourceIdType::NAVIGATION_ID);
+  DCHECK(!navigation_data.url.is_empty());
 }
 
 UkmSource::~UkmSource() = default;
 
-void UkmSource::UpdateUrl(const GURL& url) {
-  DCHECK(!url.is_empty());
-  if (url_ == url)
+void UkmSource::UpdateUrl(const GURL& new_url) {
+  DCHECK(!new_url.is_empty());
+  if (url() == new_url)
     return;
-  // We only track multiple URLs for navigation-based Sources.  These are
-  // currently the only sources that intentionally record multiple entries,
-  // and this makes it easier to compare other source URLs against a
-  // whitelist.
-  if (initial_url_.is_empty() &&
-      GetSourceIdType(id_) == SourceIdType::NAVIGATION_ID)
-    initial_url_ = url_;
-  url_ = url;
+  navigation_data_.url = new_url;
 }
 
 void UkmSource::PopulateProto(Source* proto_source) const {
@@ -69,14 +90,16 @@
   DCHECK(!proto_source->has_initial_url());
 
   proto_source->set_id(id_);
-  proto_source->set_url(GetShortenedURL(url_));
-  if (!initial_url_.is_empty()) {
+  proto_source->set_url(GetShortenedURL(url()));
+  if (!initial_url().is_empty()) {
     DCHECK_EQ(SourceIdType::NAVIGATION_ID, GetSourceIdType(id_));
-    proto_source->set_initial_url(GetShortenedURL(initial_url_));
+    proto_source->set_initial_url(GetShortenedURL(initial_url()));
   }
 
   if (custom_tab_state_ != kCustomTabUnset)
     proto_source->set_is_custom_tab(custom_tab_state_ == kCustomTabTrue);
+
+  // TODO(csharrison): Populate other fields from |navigation_data_|.
 }
 
 }  // namespace ukm
diff --git a/services/metrics/public/cpp/ukm_source.h b/services/metrics/public/cpp/ukm_source.h
index c7b761e6..be3afb6 100644
--- a/services/metrics/public/cpp/ukm_source.h
+++ b/services/metrics/public/cpp/ukm_source.h
@@ -6,6 +6,7 @@
 #define SERVICES_METRICS_PUBLIC_CPP_UKM_SOURCE_H_
 
 #include <map>
+#include <vector>
 
 #include "base/macros.h"
 #include "base/time/time.h"
@@ -27,13 +28,46 @@
     kCustomTabFalse,
   };
 
+  // Extra navigation data associated with a particular Source. Currently, all
+  // of these members except |url| are only set for navigation id sources.
+  struct METRICS_EXPORT NavigationData {
+    // Creates a copy of this struct, replacing the URL members with sanitized
+    // versions. Currently, |sanitized_urls| expects a one or two element
+    // vector. The last element in the vector will always be the final URL in
+    // the redirect chain. For two-element vectors, the first URL is assumed to
+    // be the first URL in the redirect chain.
+    NavigationData CopyWithSanitizedUrls(
+        std::vector<GURL> sanitized_urls) const;
+
+    // TODO(csharrison): Convert these URLs to vector<GURL>.
+    // The final, canonical URL for this source.
+    GURL url;
+
+    // The initial URL for this source.
+    GURL initial_url;
+
+    // The previous source id for this tab.
+    SourceId previous_source_id = kInvalidSourceId;
+
+    // The source id for the source which opened this tab. This should be set to
+    // kInvalidSourceId for all but the first navigation in the tab.
+    SourceId opener_source_id = kInvalidSourceId;
+
+    // A unique identifier for the tab the source navigated in. Tab ids should
+    // be increasing over time within a session.
+    int64_t tab_id = 0;
+  };
+
   UkmSource(SourceId id, const GURL& url);
+  UkmSource(SourceId id, const NavigationData& data);
   ~UkmSource();
 
   ukm::SourceId id() const { return id_; }
 
-  const GURL& initial_url() const { return initial_url_; }
-  const GURL& url() const { return url_; }
+  const GURL& initial_url() const { return navigation_data_.initial_url; }
+  const GURL& url() const { return navigation_data_.url; }
+
+  const NavigationData& navigation_data() const { return navigation_data_; }
 
   // The object creation time. This is for internal purposes only and is not
   // intended to be anything useful for UKM clients.
@@ -51,13 +85,7 @@
  private:
   const ukm::SourceId id_;
 
-  // The final, canonical URL for this source.
-  GURL url_;
-
-  // The initial URL for this source.
-  // Only set for navigation-id based sources where more than one value of URL
-  // was recorded.
-  GURL initial_url_;
+  NavigationData navigation_data_;
 
   // A flag indicating if metric was collected in a custom tab. This is set
   // automatically when the object is created and so represents the state when
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index c2d7424..94a7354 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -197,6 +197,8 @@
 #define SK_SUPPORT_LEGACY_AAA_CHOICE
 #endif
 
+#define SK_LEGACY_SRGB_GAMUT
+
 ///////////////////////// Imported from BUILD.gn and skia_common.gypi
 
 /* In some places Skia can use static initializers for global initialization,
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 5e57522..c09235a 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -3081,18 +3081,6 @@
             ]
         }
     ],
-    "PasswordGeneration": [
-        {
-            "platforms": [
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Disabled"
-                }
-            ]
-        }
-    ],
     "PasswordGenerationRequirements": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 616b928f..903054f 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -272178,7 +272178,7 @@
    "support"
   ],
   "./lint.whitelist": [
-   "0d41c5bf938139df76415ca163eb9b710b12b5d1",
+   "eef9476c7b17efba66c149228d3502ad57c93e9d",
    "support"
   ],
   "./update-built-tests.sh": [
@@ -340818,7 +340818,7 @@
    "support"
   ],
   "css/css-values/reference/vh_not_refreshing_on_chrome-ref.html": [
-   "affece13e73e451198a986146abde869b90c64cb",
+   "97099b75a3a25ce05a91cb8e5d0ef16c2e12cf08",
    "support"
   ],
   "css/css-values/reference/vh_not_refreshing_on_chrome_iframe-ref.html": [
@@ -341010,7 +341010,7 @@
    "support"
   ],
   "css/css-values/support/vh_not_refreshing_on_chrome_iframe.html": [
-   "95f9582bf94c0bc60ddee79415b763af8762faf0",
+   "94a0c9d232d89f8909423be965190529af57a6c8",
    "support"
   ],
   "css/css-values/unset-value-storage.html": [
@@ -341078,7 +341078,7 @@
    "support"
   ],
   "css/css-values/vh_not_refreshing_on_chrome.html": [
-   "b95d1e9054aaaa9c9a780fd4852307ed3604d46a",
+   "fd11677496279f408db5259006c195b5d88c2de6",
    "reftest"
   ],
   "css/css-values/viewport-relative-lengths-scaled-viewport.html": [
@@ -372890,7 +372890,7 @@
    "support"
   ],
   "html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez-ref.html": [
-   "329637fd6312e198937660dec52e9ff369b4e0eb",
+   "fbdccb221246144ece618469e1e21da2b5cdb48e",
    "support"
   ],
   "html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-values/reference/vh_not_refreshing_on_chrome-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-values/reference/vh_not_refreshing_on_chrome-ref.html
index 32ce9ada..279d1c6 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-values/reference/vh_not_refreshing_on_chrome-ref.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-values/reference/vh_not_refreshing_on_chrome-ref.html
@@ -36,10 +36,10 @@
 			var frameTest = document.getElementById('frameTest');
 
 			// let's resize the iframe vertically only, showing that the vh sizes is not updated.
-			if (height <= 300) {
+			if (height < 300) {
 
 				//frameTest.style.width = height++ + "px";
-				frameTest.style.height = height++ + "px";
+				frameTest.style.height = ++height + "px";
 
 				setTimeout(resizeReference, 10);
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-values/support/vh_not_refreshing_on_chrome_iframe.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-values/support/vh_not_refreshing_on_chrome_iframe.html
index c58ec57..8d8e9b49 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-values/support/vh_not_refreshing_on_chrome_iframe.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-values/support/vh_not_refreshing_on_chrome_iframe.html
@@ -78,8 +78,12 @@
 
 	setTimeout(animate, 20);
 
-	addEventListener('transitionend', function() {
-		parent.postMessage('testBoxWithTransition', '*');
+	addEventListener('transitionend', event => {
+		if (event.propertyName == 'width') {
+			// Stop any further transitons.
+			testBoxWithTransition.style.transitionProperty = 'none';
+			parent.postMessage('testBoxWithTransition', '*');
+		}
 	}, false);
 	var transitionedTestBoxStyle = document.getElementById('testBoxWithTransition').style;
 	transitionedTestBoxStyle.height = "60px";
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-values/vh_not_refreshing_on_chrome.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-values/vh_not_refreshing_on_chrome.html
index b4e0a41..52a45a114 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-values/vh_not_refreshing_on_chrome.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-values/vh_not_refreshing_on_chrome.html
@@ -39,10 +39,10 @@
 			var frameTest = document.getElementById('frameTest');
 
 			// let's resize the iframe vertically only, showing that the vh sizes is not updated.
-			if (height <= 300) {
+			if (height < 300) {
 
 				//frameTest.style.width = height++ + "px";
-				frameTest.style.height = height++ + "px";
+				frameTest.style.height = ++height + "px";
 
 				setTimeout(resizeReference, 10);
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fullscreen/rendering/fullscreen-root-block-size-manual.html b/third_party/WebKit/LayoutTests/external/wpt/fullscreen/rendering/fullscreen-root-block-size-manual.html
new file mode 100644
index 0000000..989a85d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/fullscreen/rendering/fullscreen-root-block-size-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<style>
+  html, body {
+    margin: 0px;
+  }
+</style>
+<title>fullscreen root block sizing</title>
+<!-- This page intentionally has no content. It needs to have
+no width or height. This is to ensure that the root element
+gets sizing in fullscreen mode as it does in as it does not
+in fullscreen mode.
+-->
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+async_test(t => {
+  document.onfullscreenchange = t.step_func_done(() => {
+    assert_equals(document.fullscreenElement, document.documentElement);
+    assert_true(document.documentElement.getBoundingClientRect().width > 0);
+  });
+  document.documentElement.addEventListener('click', e => {
+      document.documentElement.requestFullscreen();
+  }, {once: true});
+  test_driver.click(document.documentElement);
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez-ref.html b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez-ref.html
index c0db2d7..8200e67 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez-ref.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez-ref.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <title>Reference for Fieldset and transform: translateZ(0)</title>
 <style>
-fieldset { background: #eee; }
+fieldset { background: #eee; margin: 0 0 10px; }
 </style>
 <p>It should say PASS below without anything obscuring the text.</p>
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
index 5e4d06c..8c6bb2d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
+++ b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
@@ -100,7 +100,7 @@
 # Intentional use of print statements
 PRINT STATEMENT: dom/nodes/Document-createElement-namespace-tests/generate.py
 PRINT STATEMENT: encrypted-media/polyfill/make-polyfill-tests.py
-PRINT STATEMENT: webdriver/tests/support/fixtures.py
+PRINT STATEMENT: webdriver/tests/support/helpers.py
 
 # semi-legitimate use of console.*
 CONSOLE: console/*
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn
index 0c7a224..1e003b94 100644
--- a/third_party/android_deps/BUILD.gn
+++ b/third_party/android_deps/BUILD.gn
@@ -133,6 +133,21 @@
   ]
 }
 
+# Annotation processors for Dagger2.
+java_annotation_processor("dagger_processor") {
+  main_class = "dagger.internal.codegen.ComponentProcessor"
+  deps = [
+    ":com_google_dagger_dagger_compiler_java",
+  ]
+}
+
+java_annotation_processor("dagger_android_processor") {
+  main_class = "dagger.android.processor.AndroidProcessor"
+  deps = [
+    ":com_google_dagger_dagger_android_processor_java",
+  ]
+}
+
 # The section below is generated by running
 # `//tools/android/roll/android_deps/fetch_all.sh`
 
@@ -458,6 +473,66 @@
       "libs/com_google_android_play_core/com_google_android_play_core.info"
 }
 
+java_prebuilt("com_google_dagger_dagger_java") {
+  jar_path = "libs/com_google_dagger_dagger/dagger-2.17.jar"
+  output_name = "com_google_dagger_dagger"
+  supports_android = true
+  deps = [
+    ":javax_inject_javax_inject_java",
+  ]
+}
+
+android_aar_prebuilt("com_google_dagger_dagger_android_java") {
+  aar_path = "libs/com_google_dagger_dagger_android/dagger-android-2.17.aar"
+  info_path = "libs/com_google_dagger_dagger_android/com_google_dagger_dagger_android.info"
+  deps = [
+    ":com_android_support_support_annotations_java",
+    ":com_google_dagger_dagger_java",
+    ":javax_inject_javax_inject_java",
+  ]
+}
+
+java_prebuilt("com_google_dagger_dagger_android_processor_java") {
+  jar_path = "libs/com_google_dagger_dagger_android_processor/dagger-android-processor-2.17.jar"
+  output_name = "com_google_dagger_dagger_android_processor"
+  deps = [
+    ":com_google_dagger_dagger_android_jarimpl_java",
+    ":com_google_dagger_dagger_android_support_jarimpl_java",
+    ":com_google_dagger_dagger_java",
+    ":com_google_googlejavaformat_google_java_format_java",
+    ":com_google_guava_guava_java",
+    ":com_squareup_javapoet_java",
+  ]
+}
+
+android_aar_prebuilt("com_google_dagger_dagger_android_support_java") {
+  aar_path = "libs/com_google_dagger_dagger_android_support/dagger-android-support-2.17.aar"
+  info_path = "libs/com_google_dagger_dagger_android_support/com_google_dagger_dagger_android_support.info"
+  deps = [
+    ":com_android_support_appcompat_v7_java",
+    ":com_android_support_support_annotations_java",
+    ":com_android_support_support_fragment_java",
+    ":com_google_dagger_dagger_android_java",
+    ":com_google_dagger_dagger_java",
+    ":javax_inject_javax_inject_java",
+  ]
+}
+
+java_prebuilt("com_google_dagger_dagger_compiler_java") {
+  jar_path = "libs/com_google_dagger_dagger_compiler/dagger-compiler-2.17.jar"
+  output_name = "com_google_dagger_dagger_compiler"
+  deps = [
+    ":com_google_dagger_dagger_java",
+    ":com_google_dagger_dagger_producers_java",
+    ":com_google_dagger_dagger_spi_java",
+    ":com_google_googlejavaformat_google_java_format_java",
+    ":com_google_guava_guava_java",
+    ":com_squareup_javapoet_java",
+    ":javax_annotation_jsr250_api_java",
+    ":javax_inject_javax_inject_java",
+  ]
+}
+
 java_prebuilt("android_arch_core_common_java") {
   jar_path = "libs/android_arch_core_common/common-1.0.0.jar"
   output_name = "android_arch_core_common"
@@ -622,4 +697,80 @@
     ":com_google_android_gms_play_services_basement_java",
   ]
 }
+
+java_prebuilt("com_google_dagger_dagger_android_jarimpl_java") {
+  jar_path = "libs/com_google_dagger_dagger_android_jarimpl/dagger-android-jarimpl-2.17.jar"
+  output_name = "com_google_dagger_dagger_android_jarimpl"
+  visibility = [ ":*" ]
+}
+
+java_prebuilt("com_google_dagger_dagger_android_support_jarimpl_java") {
+  jar_path = "libs/com_google_dagger_dagger_android_support_jarimpl/dagger-android-support-jarimpl-2.17.jar"
+  output_name = "com_google_dagger_dagger_android_support_jarimpl"
+  visibility = [ ":*" ]
+}
+
+java_prebuilt("com_google_dagger_dagger_producers_java") {
+  jar_path = "libs/com_google_dagger_dagger_producers/dagger-producers-2.17.jar"
+  output_name = "com_google_dagger_dagger_producers"
+  visibility = [ ":*" ]
+  deps = [
+    ":com_google_dagger_dagger_java",
+    ":com_google_guava_guava_java",
+    ":javax_inject_javax_inject_java",
+  ]
+}
+
+java_prebuilt("com_google_dagger_dagger_spi_java") {
+  jar_path = "libs/com_google_dagger_dagger_spi/dagger-spi-2.17.jar"
+  output_name = "com_google_dagger_dagger_spi"
+  visibility = [ ":*" ]
+  deps = [
+    ":com_google_dagger_dagger_java",
+    ":com_google_dagger_dagger_producers_java",
+    ":com_google_guava_guava_java",
+    ":javax_inject_javax_inject_java",
+  ]
+}
+
+java_prebuilt("com_google_errorprone_javac_shaded_java") {
+  jar_path =
+      "libs/com_google_errorprone_javac_shaded/javac-shaded-9-dev-r4023-3.jar"
+  output_name = "com_google_errorprone_javac_shaded"
+  visibility = [ ":*" ]
+}
+
+java_prebuilt("com_google_googlejavaformat_google_java_format_java") {
+  jar_path = "libs/com_google_googlejavaformat_google_java_format/google-java-format-1.5.jar"
+  output_name = "com_google_googlejavaformat_google_java_format"
+  visibility = [ ":*" ]
+  deps = [
+    ":com_google_errorprone_javac_shaded_java",
+    ":com_google_guava_guava_java",
+  ]
+}
+
+java_prebuilt("com_google_guava_guava_java") {
+  jar_path = "libs/com_google_guava_guava/guava-25.0.jar"
+  output_name = "com_google_guava_guava"
+  visibility = [ ":*" ]
+}
+
+java_prebuilt("com_squareup_javapoet_java") {
+  jar_path = "libs/com_squareup_javapoet/javapoet-1.11.0.jar"
+  output_name = "com_squareup_javapoet"
+  visibility = [ ":*" ]
+}
+
+java_prebuilt("javax_annotation_jsr250_api_java") {
+  jar_path = "libs/javax_annotation_jsr250_api/jsr250-api-1.0.jar"
+  output_name = "javax_annotation_jsr250_api"
+  visibility = [ ":*" ]
+}
+
+java_prebuilt("javax_inject_javax_inject_java") {
+  jar_path = "libs/javax_inject_javax_inject/javax.inject-1.jar"
+  output_name = "javax_inject_javax_inject"
+  supports_android = true
+}
 # === Generated Code End ===
diff --git a/third_party/android_deps/additional_readme_paths.json b/third_party/android_deps/additional_readme_paths.json
index 98a57b1..3cad314 100644
--- a/third_party/android_deps/additional_readme_paths.json
+++ b/third_party/android_deps/additional_readme_paths.json
@@ -45,5 +45,20 @@
     "libs/com_google_android_gms_play_services_tasks",
     "libs/com_google_android_gms_play_services_vision",
     "libs/com_google_android_gms_play_services_vision_common",
-    "libs/com_google_android_play_core"
+    "libs/com_google_android_play_core",
+    "libs/com_google_dagger_dagger",
+    "libs/com_google_dagger_dagger_android",
+    "libs/com_google_dagger_dagger_android_jarimpl",
+    "libs/com_google_dagger_dagger_android_processor",
+    "libs/com_google_dagger_dagger_android_support",
+    "libs/com_google_dagger_dagger_android_support_jarimpl",
+    "libs/com_google_dagger_dagger_compiler",
+    "libs/com_google_dagger_dagger_producers",
+    "libs/com_google_dagger_dagger_spi",
+    "libs/com_google_errorprone_javac_shaded",
+    "libs/com_google_googlejavaformat_google_java_format",
+    "libs/com_google_guava_guava",
+    "libs/com_squareup_javapoet",
+    "libs/javax_annotation_jsr250_api",
+    "libs/javax_inject_javax_inject"
 ]
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger/README.chromium
new file mode 100644
index 0000000..7adc1e2
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger
+Short Name: dagger
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger/cipd.yaml
new file mode 100644
index 0000000..2aae831
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger
+description: Dagger
+data:
+- file: dagger-2.17.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger_android/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger_android/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_android/README.chromium
new file mode 100644
index 0000000..bf16393e
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger Android
+Short Name: dagger-android
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger_android/cipd.yaml
new file mode 100644
index 0000000..fa22f731
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android/cipd.yaml
@@ -0,0 +1,11 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger_android
+description: Dagger Android
+data:
+- file: dagger-android-2.17.aar
+- file: com_google_dagger_dagger_android.info
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl/README.chromium
new file mode 100644
index 0000000..e4b37b2
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger Android (Jar Impl)
+Short Name: dagger-android-jarimpl
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl/cipd.yaml
new file mode 100644
index 0000000..a9f2b29a
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger_android_jarimpl
+description: Dagger Android (Jar Impl)
+data:
+- file: dagger-android-jarimpl-2.17.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger_android_processor/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger_android_processor/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android_processor/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_android_processor/README.chromium
new file mode 100644
index 0000000..26fdd17
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android_processor/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger Android Processor
+Short Name: dagger-android-processor
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android_processor/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger_android_processor/cipd.yaml
new file mode 100644
index 0000000..6ac6881
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android_processor/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger_android_processor
+description: Dagger Android Processor
+data:
+- file: dagger-android-processor-2.17.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger_android_support/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger_android_support/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android_support/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_android_support/README.chromium
new file mode 100644
index 0000000..e2ba64b1
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android_support/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger Android Support
+Short Name: dagger-android-support
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android_support/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger_android_support/cipd.yaml
new file mode 100644
index 0000000..2882f3e
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android_support/cipd.yaml
@@ -0,0 +1,11 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger_android_support
+description: Dagger Android Support
+data:
+- file: dagger-android-support-2.17.aar
+- file: com_google_dagger_dagger_android_support.info
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl/README.chromium
new file mode 100644
index 0000000..e78d226
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger Android Support (Jar Impl)
+Short Name: dagger-android-support-jarimpl
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl/cipd.yaml
new file mode 100644
index 0000000..5e1bb808
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger_android_support_jarimpl
+description: Dagger Android Support (Jar Impl)
+data:
+- file: dagger-android-support-jarimpl-2.17.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger_compiler/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_compiler/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/README.chromium
new file mode 100644
index 0000000..07906b6
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger Compiler
+Short Name: dagger-compiler
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_compiler/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/cipd.yaml
new file mode 100644
index 0000000..424ce95b
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger_compiler
+description: Dagger Compiler
+data:
+- file: dagger-compiler-2.17.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger_producers/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger_producers/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_producers/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_producers/README.chromium
new file mode 100644
index 0000000..a84ad2e
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_producers/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger Producers
+Short Name: dagger-producers
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_producers/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger_producers/cipd.yaml
new file mode 100644
index 0000000..f839855
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_producers/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger_producers
+description: Dagger Producers
+data:
+- file: dagger-producers-2.17.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_dagger_dagger_spi/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_dagger_dagger_spi/LICENSE
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_spi/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_spi/README.chromium
new file mode 100644
index 0000000..a3776d9
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_spi/README.chromium
@@ -0,0 +1,13 @@
+Name: Dagger Spi
+Short Name: dagger-spi
+URL: https://github.com/google/dagger
+Version: 2.17
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+A fast dependency injector for Android and Java.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_spi/cipd.yaml b/third_party/android_deps/libs/com_google_dagger_dagger_spi/cipd.yaml
new file mode 100644
index 0000000..46c68ad
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_spi/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.13-cr0
+package: chromium/third_party/android_deps/libs/com_google_dagger_dagger_spi
+description: A fast dependency injector for Android and Java
+data:
+- file: dagger-spi-2.17.jar
diff --git a/third_party/android_deps/libs/com_google_errorprone_javac_shaded/LICENSE b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/LICENSE
new file mode 100644
index 0000000..c322c37
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/LICENSE
@@ -0,0 +1,373 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii" /><title>OpenJDK: GPLv2 + Classpath Exception</title><link rel="shortcut icon" href="../images/nanoduke.ico" /><link rel="stylesheet" type="text/css" href="../page.css" /><script type="text/javascript" src="../page.js"><noscript></noscript></script></head><body><div id="main">
+<h1>GNU General Public License, version 2,<br />
+with the Classpath Exception</h1>
+<pre>
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it.  By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.  This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it.  (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price.  Our
+General Public Licenses are designed to make sure that you have the freedom to
+distribute copies of free software (and charge for this service if you wish),
+that you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs; and that you know you
+can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny
+you these rights or to ask you to surrender the rights.  These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for
+a fee, you must give the recipients all the rights that you have.  You must
+make sure that they, too, receive or can get the source code.  And you must
+show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software.  If the
+software is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents.  We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program proprietary.
+To prevent this, we have made it clear that any patent must be licensed for
+everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms of
+this General Public License.  The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or
+translated into another language.  (Hereinafter, translation is included
+without limitation in the term "modification".) Each licensee is addressed as
+"you".
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope.  The act of running the Program is
+not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by
+running the Program).  Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as
+you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the
+Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus
+forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+    a) You must cause the modified files to carry prominent notices stating
+    that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in whole or
+    in part contains or is derived from the Program or any part thereof, to be
+    licensed as a whole at no charge to all third parties under the terms of
+    this License.
+
+    c) If the modified program normally reads commands interactively when run,
+    you must cause it, when started running for such interactive use in the
+    most ordinary way, to print or display an announcement including an
+    appropriate copyright notice and a notice that there is no warranty (or
+    else, saying that you provide a warranty) and that users may redistribute
+    the program under these conditions, and telling the user how to view a copy
+    of this License.  (Exception: if the Program itself is interactive but does
+    not normally print such an announcement, your work based on the Program is
+    not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License, and
+its terms, do not apply to those sections when you distribute them as separate
+works.  But when you distribute the same sections as part of a whole which is a
+work based on the Program, the distribution of the whole must be on the terms
+of this License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on
+the Program.
+
+In addition, mere aggregation of another work not based on the Program with the
+Program (or with a work based on the Program) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1 and
+2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable source
+    code, which must be distributed under the terms of Sections 1 and 2 above
+    on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three years, to
+    give any third party, for a charge no more than your cost of physically
+    performing source distribution, a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of Sections 1
+    and 2 above on a medium customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer to
+    distribute corresponding source code.  (This alternative is allowed only
+    for noncommercial distribution and only if you received the program in
+    object code or executable form with such an offer, in accord with
+    Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it.  For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable.  However, as a special exception, the source code
+distributed need not include anything that is normally distributed (in either
+source or binary form) with the major components (compiler, kernel, and so on)
+of the operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the source
+code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License.  Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License.  However, parties who have received copies, or
+rights, from you under this License will not have their licenses terminated so
+long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the Program
+or its derivative works.  These actions are prohibited by law if you do not
+accept this License.  Therefore, by modifying or distributing the Program (or
+any work based on the Program), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor to
+copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of the
+rights granted herein.  You are not responsible for enforcing compliance by
+third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License.  If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices.  Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded.  In
+such case, this License incorporates the limitation as if written in the body
+of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the
+General Public License from time to time.  Such new versions will be similar in
+spirit to the present version, but may differ in detail to address new problems
+or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any later
+version", you have the option of following the terms and conditions either of
+that version or of any later version published by the Free Software Foundation.
+If the Program does not specify a version number of this License, you may
+choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission.  For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
+PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program.  It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+    One line to give the program's name and a brief idea of what it does.
+
+    Copyright (C) &lt;year&gt; &lt;name of author&gt;
+
+    This program is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the Free
+    Software Foundation; either version 2 of the License, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc., 59
+    Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it
+starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+    with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free
+    software, and you are welcome to redistribute it under certain conditions;
+    type 'show c' for details.
+
+The hypothetical commands 'show w' and 'show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may be
+called something other than 'show w' and 'show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.  Here
+is a sample; alter the names:
+
+    Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+    'Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+    signature of Ty Coon, 1 April 1989
+
+    Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General Public
+License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL
+
+Certain source files distributed by Oracle America and/or its affiliates are
+subject to the following clarification and special exception to the GPL, but
+only where Oracle has expressly included in the particular source file's header
+the words "Oracle designates this particular file as subject to the "Classpath"
+exception as provided by Oracle in the LICENSE file that accompanied this code."
+
+    Linking this library statically or dynamically with other modules is making
+    a combined work based on this library.  Thus, the terms and conditions of
+    the GNU General Public License cover the whole combination.
+
+    As a special exception, the copyright holders of this library give you
+    permission to link this library with independent modules to produce an
+    executable, regardless of the license terms of these independent modules,
+    and to copy and distribute the resulting executable under terms of your
+    choice, provided that you also meet, for each linked independent module,
+    the terms and conditions of the license of that module.  An independent
+    module is a module which is not derived from or based on this library.  If
+    you modify this library, you may extend this exception to your version of
+    the library, but you are not obligated to do so.  If you do not wish to do
+    so, delete this exception statement from your version.
+</pre>
+</div><div id="sidebar"><div id="openjdk-sidebar-logo"><a href="/"><img alt="OpenJDK logo" src="../images/openjdk-small.png" /></a></div><div class="links"><div class="links"><a href="/workshop"><b>Workshop</b></a></div></div><div class="links"><div class="link"><a href="/faq/">OpenJDK FAQ</a></div><div class="link"><a href="/install/">Installing</a></div><div class="link"><a href="/contribute/">Contributing</a></div><div class="link"><a href="/sponsor/">Sponsoring</a></div><div class="link"><a href="/guide/">Developers' Guide</a></div></div><div class="links"><div class="links"><a href="http://mail.openjdk.java.net">Mailing lists</a></div><div class="link"><a href="/irc">IRC</a>
+                      &#183; <a href="http://wiki.openjdk.java.net">Wiki</a></div></div><div class="links"><div class="links"><a href="/bylaws">Bylaws</a> &#183; <a href="/census">Census</a></div><div class="link"><a href="/legal/">Legal</a></div></div><div class="links"><div class="links"><a href="/jeps/0"><b>JEP Process</b></a></div></div><div class="links"><div class="link search"><form method="get" action="http://www.google.com/search"><input id="searchBox" style="color: gray" type="text" name="q" size="10" maxlength="255" value="search" /><input type="hidden" name="sitesearch" value="openjdk.java.net" /></form></div></div><div class="links"><div class="about">Source code</div><div class="link"><a href="http://hg.openjdk.java.net">Mercurial</a></div><div class="link">Bundles (<a href="http://download.java.net/openjdk/jdk6">6</a>)</div></div><div class="links"><div class="about">Groups</div><div class="link"><a href="/groups/">(overview)</a></div><div class="link"><a href="/groups/2d">2D Graphics</a></div><div class="link"><a href="/groups/adoption">Adoption</a></div><div class="link"><a href="/groups/awt">AWT</a></div><div class="link"><a href="/groups/build">Build</a></div><div class="link"><a href="/groups/csr">Compatibility &amp; Specification Review</a></div><div class="link"><a href="/groups/compiler">Compiler</a></div><div class="link"><a href="/groups/conformance">Conformance</a></div><div class="link"><a href="/groups/core-libs">Core Libraries</a></div><div class="link"><a href="/groups/gb">Governing Board</a></div><div class="link"><a href="/groups/hotspot">HotSpot</a></div><div class="link"><a href="/groups/i18n">Internationalization</a></div><div class="link"><a href="/groups/jmx">JMX</a></div><div class="link"><a href="/groups/members">Members</a></div><div class="link"><a href="/groups/net">Networking</a></div><div class="link"><a href="/groups/nb-projects">NetBeans Projects</a></div><div class="link"><a href="/groups/porters">Porters</a></div><div class="link"><a href="/groups/quality">Quality</a></div><div class="link"><a href="/groups/security">Security</a></div><div class="link"><a href="/groups/serviceability">Serviceability</a></div><div class="link"><a href="/groups/sound">Sound</a></div><div class="link"><a href="/groups/swing">Swing</a></div><div class="link"><a href="/groups/vulnerability">Vulnerability</a></div><div class="link"><a href="/groups/web">Web</a></div></div><div class="links"><div class="about">Projects</div><div class="link"><a href="/projects/">(overview)</a></div><div class="link"><a href="/projects/amber">Amber</a></div><div class="link"><a href="/projects/anno-pipeline">Annotations Pipeline 2.0</a></div><div class="link"><a href="/projects/audio-engine">Audio Engine</a></div><div class="link"><a href="/projects/build-infra">Build Infrastructure</a></div><div class="link"><a href="/projects/caciocavallo">Caciocavallo</a></div><div class="link"><a href="/projects/closures">Closures</a></div><div class="link"><a href="/projects/code-tools">Code Tools</a></div><div class="link"><a href="/projects/coin">Coin</a></div><div class="link"><a href="/projects/cvmi">Common VM Interface</a></div><div class="link"><a href="/projects/compiler-grammar">Compiler Grammar</a></div><div class="link"><a href="/projects/detroit">Detroit</a></div><div class="link"><a href="/projects/dio">Device I/O</a></div><div class="link"><a href="/projects/duke">Duke</a></div><div class="link"><a href="/projects/font-scaler">Font Scaler</a></div><div class="link"><a href="/projects/fbtoolkit">Framebuffer Toolkit</a></div><div class="link"><a href="/projects/graal">Graal</a></div><div class="link"><a href="/projects/graphics-rasterizer">Graphics Rasterizer</a></div><div class="link"><a href="/projects/harfbuzz">HarfBuzz Integration</a></div><div class="link"><a href="/projects/icedtea">IcedTea</a></div><div class="link"><a href="/projects/jdk6">JDK 6</a></div><div class="link"><a href="/projects/jdk7">JDK 7</a></div><div class="link"><a href="/projects/jdk7u">JDK 7 Updates</a></div><div class="link"><a href="/projects/jdk8">JDK 8</a></div><div class="link"><a href="/projects/jdk8u">JDK 8 Updates</a></div><div class="link"><a href="/projects/jdk9">JDK 9</a></div><div class="link"><a href="/projects/jdk">JDK</a>
+      (<a href="/projects/jdk/10">10</a>,
+       <a href="/projects/jdk/11">11</a>)</div><div class="link"><a href="/projects/jdk-updates">JDK Updates</a></div><div class="link"><a href="/projects/javadoc-next">JavaDoc.Next</a></div><div class="link"><a href="/projects/jigsaw">Jigsaw</a></div><div class="link"><a href="/projects/kona">Kona</a></div><div class="link"><a href="/projects/kulla">Kulla</a></div><div class="link"><a href="/projects/lambda">Lambda</a></div><div class="link"><a href="/projects/locale-enhancement">Locale Enhancement</a></div><div class="link"><a href="/projects/loom">Loom</a></div><div class="link"><a href="/projects/jmm">Memory Model Update</a></div><div class="link"><a href="/projects/metropolis">Metropolis</a></div><div class="link"><a href="/projects/jmc">Mission Control</a></div><div class="link"><a href="/projects/mobile">Mobile</a></div><div class="link"><a href="/projects/modules">Modules</a></div><div class="link"><a href="/projects/mlvm">Multi-Language VM</a></div><div class="link"><a href="/projects/nashorn">Nashorn</a></div><div class="link"><a href="/projects/nio">New I/O</a></div><div class="link"><a href="/projects/openjfx">OpenJFX</a></div><div class="link"><a href="/projects/panama">Panama</a></div><div class="link"><a href="/projects/penrose">Penrose</a></div><div class="link"><a href="/projects/aarch32-port">Port: AArch32</a></div><div class="link"><a href="/projects/aarch64-port">Port: AArch64</a></div><div class="link"><a href="/projects/bsd-port">Port: BSD</a></div><div class="link"><a href="/projects/haiku-port">Port: Haiku</a></div><div class="link"><a href="/projects/macosx-port">Port: Mac OS X</a></div><div class="link"><a href="/projects/mips-port">Port: MIPS</a></div><div class="link"><a href="/projects/ppc-aix-port">Port: PowerPC/AIX</a></div><div class="link"><a href="/projects/s390x-port">Port: s390x</a></div><div class="link"><a href="/projects/portola">Portola</a></div><div class="link"><a href="/projects/sctp">SCTP</a></div><div class="link"><a href="/projects/shenandoah">Shenandoah</a></div><div class="link"><a href="/projects/sumatra">Sumatra</a></div><div class="link"><a href="/projects/threeten">ThreeTen</a></div><div class="link"><a href="/projects/tiered-attrib">Tiered Attribution</a></div><div class="link"><a href="/projects/type-annotations">Type Annotations</a></div><div class="link"><a href="/projects/xrender">XRender Pipeline</a></div><div class="link"><a href="/projects/valhalla">Valhalla</a></div><div class="link"><a href="/projects/verona">Verona</a></div><div class="link"><a href="/projects/visualvm">VisualVM</a></div><div class="link"><a href="/projects/zero">Zero</a></div><div class="link"><a href="/projects/zgc">ZGC</a></div></div><div class="links"><div class="about">Tools</div><div class="link"><a href="http://java.sun.com/javase/downloads/index.jsp">Java SE</a></div><div class="link"><a href="http://www.selenic.com/mercurial/">Mercurial</a></div><div class="link"><a href="http://netbeans.org">NetBeans</a></div><div class="link"><a href="/jtreg/index.html">jtreg harness</a></div></div><div class="links"><div class="about">Community</div><div class="link"><a href="http://planetjdk.org">Planet JDK blogs</a></div><div class="link"><a href="http://blogs.oracle.com/theaquarium">The Aquarium</a></div><div class="link"><a href="http://java.sun.com">java.sun.com</a></div><div class="link"><a href="http://jcp.org">Java Community Process</a></div></div><div class="links"><div class="about">Related</div><div class="link">JDK Snapshots (<a href="http://jdk.java.net/8/">8u</a>,
+       <a href="http://jdk.java.net/9/">9</a>,
+       <a href="http://jdk.java.net/10/">10</a>,
+       <a href="http://jdk.java.net/11/">11</a>) </div><div class="link"><a href="http://javaee.github.io/glassfish/">GlassFish</a></div></div><div class="buttons"><a href="http://oracle.com"><img alt="Oracle logo" src="../images/oracle.png" /></a></div></div><div id="footer">
+
+        &#169; 2018 Oracle Corporation and/or its affiliates
+        <br /><a href="/legal/tou/">Terms of Use</a>
+        &#183;
+        
+            License: <a href="/legal/gplv2+ce.html">GPLv2</a>
+        &#183; <a href="http://www.oracle.com/us/legal/privacy/">Privacy</a>
+        &#183; <a href="http://www.oracle.com/us/legal/third-party-trademarks/third-party-trademarks-078568.html">Trademarks</a></div><SCRIPT type="text/javascript">
+  var sc_project=2527440;
+  var sc_invisible=1;
+  var sc_partition=24;
+  var sc_security="d832a704";
+  var sc_remove_link=1;
+  </SCRIPT><script type="text/javascript" src="http://www.statcounter.com/counter/counter_xhtml.js"></script><noscript><div class="statcounter"><img class="statcounter" src="http://c25.statcounter.com/counter.php?sc_project=2527440&amp;java=0&amp;security=d832a704&amp;invisible=1" alt="web statistics" /></div></noscript></body></html>
diff --git a/third_party/android_deps/libs/com_google_errorprone_javac_shaded/README.chromium b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/README.chromium
new file mode 100644
index 0000000..1f1a923
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/README.chromium
@@ -0,0 +1,13 @@
+Name: Error Prone shaded javac
+Short Name: javac-shaded
+URL: https://github.com/google/error-prone-javac
+Version: 9-dev-r4023-3
+License: GNU General Public License, version 2, with the Classpath Exception
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+A repackaged and shaded copy of javac
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_errorprone_javac_shaded/cipd.yaml b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/cipd.yaml
new file mode 100644
index 0000000..3bb671405
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:9-dev-r4023-3-cr0
+package: chromium/third_party/android_deps/libs/com_google_errorprone_javac_shaded
+description: Error Prone shaded javac
+data:
+- file: javac-shaded-9-dev-r4023-3.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/LICENSE
diff --git a/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/README.chromium b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/README.chromium
new file mode 100644
index 0000000..e57749b
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/README.chromium
@@ -0,0 +1,13 @@
+Name: Google Java Format
+Short Name: google-java-format
+URL: https://github.com/google/google-java-format
+Version: 1.4
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+A Java source code formatter that follows Google Java Style.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/cipd.yaml b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/cipd.yaml
new file mode 100644
index 0000000..78fba15
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1.4-cr0
+package: chromium/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format
+description: Google Java Format
+data:
+- file: google-java-format-1.5.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_google_guava_guava/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_google_guava_guava/LICENSE
diff --git a/third_party/android_deps/libs/com_google_guava_guava/README.chromium b/third_party/android_deps/libs/com_google_guava_guava/README.chromium
new file mode 100644
index 0000000..679b657
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_guava_guava/README.chromium
@@ -0,0 +1,13 @@
+Name: Guava: Google Core Libraries for Java
+Short Name: guava
+URL: https://github.com/google/guava
+Version: 25.0
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+Guava is a suite of core and expanded libraries that include utility classes, google's collections, io classes, and much much more. Guava has only one code dependency - javax.annotation, per the JSR-305 spec.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_guava_guava/cipd.yaml b/third_party/android_deps/libs/com_google_guava_guava/cipd.yaml
new file mode 100644
index 0000000..d486e1dc
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_guava_guava/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:21.0-cr0
+package: chromium/third_party/android_deps/libs/com_google_guava_guava
+description: Guava, Google Core Libraries for Java
+data:
+- file: guava-25.0.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/com_squareup_javapoet/LICENSE
similarity index 100%
copy from third_party/javax_inject/LICENSE
copy to third_party/android_deps/libs/com_squareup_javapoet/LICENSE
diff --git a/third_party/android_deps/libs/com_squareup_javapoet/README.chromium b/third_party/android_deps/libs/com_squareup_javapoet/README.chromium
new file mode 100644
index 0000000..95697e8b
--- /dev/null
+++ b/third_party/android_deps/libs/com_squareup_javapoet/README.chromium
@@ -0,0 +1,13 @@
+Name: JavaPoet
+Short Name: javapoet
+URL: http://github.com/square/javapoet/
+Version: 1.11.0
+License: Apache 2.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+Use beautiful Java code to generate beautiful Java code.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_squareup_javapoet/cipd.yaml b/third_party/android_deps/libs/com_squareup_javapoet/cipd.yaml
new file mode 100644
index 0000000..aae1d38
--- /dev/null
+++ b/third_party/android_deps/libs/com_squareup_javapoet/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1.8.0-cr0
+package: chromium/third_party/android_deps/libs/com_squareup_javapoet
+description: JavaPoet
+data:
+- file: javapoet-1.11.0.jar
diff --git a/third_party/android_deps/libs/javax_annotation_jsr250_api/LICENSE b/third_party/android_deps/libs/javax_annotation_jsr250_api/LICENSE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/android_deps/libs/javax_annotation_jsr250_api/LICENSE
diff --git a/third_party/android_deps/libs/javax_annotation_jsr250_api/README.chromium b/third_party/android_deps/libs/javax_annotation_jsr250_api/README.chromium
new file mode 100644
index 0000000..fd377f5
--- /dev/null
+++ b/third_party/android_deps/libs/javax_annotation_jsr250_api/README.chromium
@@ -0,0 +1,13 @@
+Name: JSR-250 Common Annotations for the JavaTM Platform
+Short Name: jsr250-api
+URL: http://jcp.org/aboutJava/communityprocess/final/jsr250/index.html
+Version: 1.0
+License: COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+JSR-250 Reference Implementation by Glassfish
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/javax_annotation_jsr250_api/cipd.yaml b/third_party/android_deps/libs/javax_annotation_jsr250_api/cipd.yaml
new file mode 100644
index 0000000..2fc6ac6b
--- /dev/null
+++ b/third_party/android_deps/libs/javax_annotation_jsr250_api/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1.0-cr0
+package: chromium/third_party/android_deps/libs/javax_annotation_jsr250_api
+description: JSR-250 Common Annotations for the JavaTM Platform
+data:
+- file: jsr250-api-1.0.jar
diff --git a/third_party/javax_inject/LICENSE b/third_party/android_deps/libs/javax_inject_javax_inject/LICENSE
similarity index 100%
rename from third_party/javax_inject/LICENSE
rename to third_party/android_deps/libs/javax_inject_javax_inject/LICENSE
diff --git a/third_party/android_deps/libs/javax_inject_javax_inject/README.chromium b/third_party/android_deps/libs/javax_inject_javax_inject/README.chromium
new file mode 100644
index 0000000..dc2aa5b
--- /dev/null
+++ b/third_party/android_deps/libs/javax_inject_javax_inject/README.chromium
@@ -0,0 +1,13 @@
+Name: javax.inject
+Short Name: javax.inject
+URL: http://code.google.com/p/atinject/
+Version: 1
+License: Apache Version 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+The javax.inject API
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/javax_inject_javax_inject/cipd.yaml b/third_party/android_deps/libs/javax_inject_javax_inject/cipd.yaml
new file mode 100644
index 0000000..8b0b186
--- /dev/null
+++ b/third_party/android_deps/libs/javax_inject_javax_inject/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1-cr0
+package: chromium/third_party/android_deps/libs/javax_inject_javax_inject
+description: javax.inject
+data:
+- file: javax.inject-1.jar
diff --git a/third_party/blink/public/platform/web_media_stream_source.h b/third_party/blink/public/platform/web_media_stream_source.h
index 1a3437bb..f4a2560 100644
--- a/third_party/blink/public/platform/web_media_stream_source.h
+++ b/third_party/blink/public/platform/web_media_stream_source.h
@@ -44,7 +44,6 @@
 
 class MediaStreamSource;
 class WebAudioDestinationConsumer;
-class WebMediaConstraints;
 class WebString;
 
 class WebMediaStreamSource {
@@ -138,8 +137,6 @@
       bool auto_gain_control,
       bool noise_supression);
 
-  BLINK_PLATFORM_EXPORT WebMediaConstraints Constraints();
-
   BLINK_PLATFORM_EXPORT void SetCapabilities(const Capabilities&);
 
   // Only used if if this is a WebAudio source.
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc
index fcbf62775..2709b98 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -56,6 +56,7 @@
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
 #include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/dom/pseudo_element.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
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 3b542f7b..ede4b1c0 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -573,9 +573,13 @@
       AdjustStyleForHTMLElement(style, ToHTMLElement(*element));
   }
   if (style.Display() != EDisplay::kNone) {
+    bool is_document_element =
+        element && element->GetDocument().documentElement() == element;
     // Per the spec, position 'static' and 'relative' in the top layer compute
-    // to 'absolute'.
-    if (IsInTopLayer(element, style) &&
+    // to 'absolute'. Root elements that are in the top layer should just
+    // be left alone because the fullscreen.css doesn't apply any style to
+    // them.
+    if (IsInTopLayer(element, style) && !is_document_element &&
         (style.GetPosition() == EPosition::kStatic ||
          style.GetPosition() == EPosition::kRelative))
       style.SetPosition(EPosition::kAbsolute);
@@ -586,7 +590,7 @@
         (style.HasOutOfFlowPosition() || style.IsFloating()))
       style.SetDisplay(EquivalentBlockDisplay(style.Display()));
 
-    if (element && element->GetDocument().documentElement() == element)
+    if (is_document_element)
       style.SetDisplay(EquivalentBlockDisplay(style.Display()));
 
     // We don't adjust the first letter style earlier because we may change the
diff --git a/third_party/blink/renderer/core/dom/comment.h b/third_party/blink/renderer/core/dom/comment.h
index f4f81ad..5b1579b 100644
--- a/third_party/blink/renderer/core/dom/comment.h
+++ b/third_party/blink/renderer/core/dom/comment.h
@@ -27,7 +27,7 @@
 
 namespace blink {
 
-class Comment final : public CharacterData {
+class CORE_EXPORT Comment final : public CharacterData {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
@@ -39,6 +39,7 @@
   String nodeName() const override;
   NodeType getNodeType() const override;
   Node* Clone(Document&, CloneChildrenFlag) const override;
+  void DetachLayoutTree(const AttachContext&) final {}
 };
 
 DEFINE_NODE_TYPE_CASTS(Comment, getNodeType() == Node::kCommentNode);
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc
index c07792de..659d355a 100644
--- a/third_party/blink/renderer/core/dom/container_node.cc
+++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -951,11 +951,34 @@
   }
 }
 
+#if DCHECK_IS_ON()
+namespace {
+
+bool AttachedAllowedWhenAttaching(Node* node) {
+  return node->getNodeType() == Node::kCommentNode ||
+         node->getNodeType() == Node::kProcessingInstructionNode;
+}
+
+bool ChildAttachedAllowedWhenAttachingChildren(ContainerNode* node) {
+  if (node->IsShadowRoot())
+    return true;
+  if (node->IsV0InsertionPoint())
+    return true;
+  if (IsHTMLSlotElement(node))
+    return true;
+  if (IsShadowHost(node))
+    return true;
+  return false;
+}
+
+}  // namespace
+#endif
+
 DISABLE_CFI_PERF
 void ContainerNode::AttachLayoutTree(AttachContext& context) {
   for (Node* child = firstChild(); child; child = child->nextSibling()) {
 #if DCHECK_IS_ON()
-    DCHECK(child->NeedsAttach() ||
+    DCHECK(child->NeedsAttach() || AttachedAllowedWhenAttaching(child) ||
            ChildAttachedAllowedWhenAttachingChildren(this));
 #endif
     if (child->NeedsAttach())
@@ -982,11 +1005,10 @@
   GetDocument().IncDOMTreeVersion();
   GetDocument().NotifyChangeChildren(*this);
   InvalidateNodeListCachesInAncestors(nullptr, nullptr, &change);
-  if (change.IsChildInsertion()) {
-    if (!ChildNeedsStyleRecalc()) {
-      SetChildNeedsStyleRecalc();
-      MarkAncestorsWithChildNeedsStyleRecalc();
-    }
+  if (!ChildNeedsStyleRecalc() && change.IsChildInsertion() &&
+      change.sibling_changed->NeedsStyleRecalc()) {
+    SetChildNeedsStyleRecalc();
+    MarkAncestorsWithChildNeedsStyleRecalc();
   }
 }
 
@@ -1621,22 +1643,4 @@
   return EnsureRareData().EnsureNodeLists();
 }
 
-#if DCHECK_IS_ON()
-bool ChildAttachedAllowedWhenAttachingChildren(ContainerNode* node) {
-  if (node->IsShadowRoot())
-    return true;
-
-  if (node->IsV0InsertionPoint())
-    return true;
-
-  if (IsHTMLSlotElement(node))
-    return true;
-
-  if (IsShadowHost(node))
-    return true;
-
-  return false;
-}
-#endif
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/container_node.h b/third_party/blink/renderer/core/dom/container_node.h
index dea345ca..578665e 100644
--- a/third_party/blink/renderer/core/dom/container_node.h
+++ b/third_party/blink/renderer/core/dom/container_node.h
@@ -456,10 +456,6 @@
   TraceWrapperMember<Node> last_child_;
 };
 
-#if DCHECK_IS_ON()
-bool ChildAttachedAllowedWhenAttachingChildren(ContainerNode*);
-#endif
-
 WILL_NOT_BE_EAGERLY_TRACED_CLASS(ContainerNode);
 
 DEFINE_NODE_TYPE_CASTS(ContainerNode, IsContainerNode());
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 5609708..6fb9ed3 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2124,13 +2124,6 @@
 #if DCHECK_IS_ON()
 static void AssertLayoutTreeUpdated(Node& root) {
   for (Node& node : NodeTraversal::InclusiveDescendantsOf(root)) {
-    // We leave some nodes with dirty bits in the tree because they don't
-    // matter like Comment and ProcessingInstruction nodes.
-    // TODO(esprehn): Don't even mark those nodes as needing recalcs in the
-    // first place.
-    if (!node.IsElementNode() && !node.IsTextNode() && !node.IsShadowRoot() &&
-        !node.IsDocumentNode())
-      continue;
     DCHECK(!node.NeedsStyleRecalc());
     DCHECK(!node.ChildNeedsStyleRecalc());
     DCHECK(!node.NeedsReattachLayoutTree());
diff --git a/third_party/blink/renderer/core/dom/document_type.h b/third_party/blink/renderer/core/dom/document_type.h
index 4c8a073..2a3648c 100644
--- a/third_party/blink/renderer/core/dom/document_type.h
+++ b/third_party/blink/renderer/core/dom/document_type.h
@@ -55,6 +55,7 @@
 
   InsertionNotificationRequest InsertedInto(ContainerNode&) override;
   void RemovedFrom(ContainerNode&) override;
+  void DetachLayoutTree(const AttachContext&) final {}
 
   String name_;
   String public_id_;
diff --git a/third_party/blink/renderer/core/dom/events/custom_event.cc b/third_party/blink/renderer/core/dom/events/custom_event.cc
index 14706ed5e..902d22a3 100644
--- a/third_party/blink/renderer/core/dom/events/custom_event.cc
+++ b/third_party/blink/renderer/core/dom/events/custom_event.cc
@@ -27,6 +27,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
+#include "third_party/blink/renderer/core/event_names.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/dom/events/event.cc b/third_party/blink/renderer/core/dom/events/event.cc
index 6dfb1ae4..ec923d4c 100644
--- a/third_party/blink/renderer/core/dom/events/event.cc
+++ b/third_party/blink/renderer/core/dom/events/event.cc
@@ -22,6 +22,8 @@
 
 #include "third_party/blink/renderer/core/dom/events/event.h"
 
+#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 #include "third_party/blink/renderer/core/dom/events/event_target.h"
 #include "third_party/blink/renderer/core/dom/static_node_list.h"
 #include "third_party/blink/renderer/core/events/focus_event.h"
@@ -29,6 +31,7 @@
 #include "third_party/blink/renderer/core/events/pointer_event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/hosts_using_features.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/svg/svg_element.h"
 #include "third_party/blink/renderer/core/timing/dom_window_performance.h"
diff --git a/third_party/blink/renderer/core/dom/events/event.h b/third_party/blink/renderer/core/dom/events/event.h
index 375e6ff..4175d84a 100644
--- a/third_party/blink/renderer/core/dom/events/event.h
+++ b/third_party/blink/renderer/core/dom/events/event.h
@@ -26,19 +26,17 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_H_
 
 #include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
-#include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
-#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
-#include "third_party/blink/renderer/core/dom/events/event_init.h"
-#include "third_party/blink/renderer/core/dom/events/event_path.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_result.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/text/atomic_string.h"
-#include "third_party/blink/renderer/platform/wtf/time.h"
 
 namespace blink {
 
 class DOMWrapperWorld;
+class EventDispatcher;
+class EventInit;
+class EventPath;
 class EventTarget;
 class ScriptState;
 class ScriptValue;
diff --git a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
index d3c0f5d..237bdff2 100644
--- a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
+++ b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
@@ -33,6 +33,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
 #include "third_party/blink/renderer/core/dom/events/window_event_context.h"
 #include "third_party/blink/renderer/core/events/mouse_event.h"
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index 9a33399..32f58a1 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -908,6 +908,8 @@
   DCHECK(change_type != kNoStyleChange);
   if (!InActiveDocument())
     return;
+  if (!IsContainerNode() && !IsTextNode())
+    return;
 
   TRACE_EVENT_INSTANT1(
       TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h
index 7fab6331..cdba436 100644
--- a/third_party/blink/renderer/core/dom/node.h
+++ b/third_party/blink/renderer/core/dom/node.h
@@ -932,7 +932,7 @@
 
  protected:
   enum ConstructionType {
-    kCreateOther = kDefaultNodeFlags,
+    kCreateOther = kIsFinishedParsingChildrenFlag,
     kCreateText = kDefaultNodeFlags | kIsTextFlag,
     kCreateContainer =
         kDefaultNodeFlags | kChildNeedsStyleRecalcFlag | kIsContainerFlag,
diff --git a/third_party/blink/renderer/core/dom/node_test.cc b/third_party/blink/renderer/core/dom/node_test.cc
index 4e2a57ef..2adc78d 100644
--- a/third_party/blink/renderer/core/dom/node_test.cc
+++ b/third_party/blink/renderer/core/dom/node_test.cc
@@ -6,9 +6,11 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
+#include "third_party/blink/renderer/core/dom/comment.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
 #include "third_party/blink/renderer/core/dom/layout_tree_builder.h"
+#include "third_party/blink/renderer/core/dom/processing_instruction.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/dom/shadow_root_init.h"
 #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
@@ -315,4 +317,21 @@
   EXPECT_TRUE(InitializeUserAgentShadowTree(node)->HasMediaControlAncestor());
 }
 
+TEST_F(NodeTest, appendChildProcessingInstructionNoStyleRecalc) {
+  GetDocument().View()->UpdateAllLifecyclePhases();
+  EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+  ProcessingInstruction* pi =
+      ProcessingInstruction::Create(GetDocument(), "A", "B");
+  GetDocument().body()->appendChild(pi, ASSERT_NO_EXCEPTION);
+  EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+}
+
+TEST_F(NodeTest, appendChildCommentNoStyleRecalc) {
+  GetDocument().View()->UpdateAllLifecyclePhases();
+  EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+  Comment* comment = Comment::Create(GetDocument(), "comment");
+  GetDocument().body()->appendChild(comment, ASSERT_NO_EXCEPTION);
+  EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.h b/third_party/blink/renderer/core/dom/processing_instruction.h
index 32b9bf7..66e8683 100644
--- a/third_party/blink/renderer/core/dom/processing_instruction.h
+++ b/third_party/blink/renderer/core/dom/processing_instruction.h
@@ -32,8 +32,8 @@
 class StyleSheet;
 class EventListener;
 
-class ProcessingInstruction final : public CharacterData,
-                                    private ResourceClient {
+class CORE_EXPORT ProcessingInstruction final : public CharacterData,
+                                                private ResourceClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(ProcessingInstruction);
 
@@ -80,6 +80,7 @@
 
   InsertionNotificationRequest InsertedInto(ContainerNode&) override;
   void RemovedFrom(ContainerNode&) override;
+  void DetachLayoutTree(const AttachContext&) final {}
 
   bool CheckStyleSheet(String& href, String& charset);
   void Process(const String& href, const String& charset);
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc
index 6ddf8c86..f9cad13 100644
--- a/third_party/blink/renderer/core/dom/range.cc
+++ b/third_party/blink/renderer/core/dom/range.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/editing/set_selection_options.h"
 #include "third_party/blink/renderer/core/editing/visible_position.h"
 #include "third_party/blink/renderer/core/editing/visible_units.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/geometry/dom_rect.h"
 #include "third_party/blink/renderer/core/geometry/dom_rect_list.h"
diff --git a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
index f73e198..4d665a4 100644
--- a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
+++ b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
@@ -44,6 +44,8 @@
 #include "third_party/blink/renderer/core/events/clipboard_event.h"
 #include "third_party/blink/renderer/core/events/text_event.h"
 #include "third_party/blink/renderer/core/frame/content_settings_client.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/html/forms/text_control_element.h"
 #include "third_party/blink/renderer/core/html/html_image_element.h"
diff --git a/third_party/blink/renderer/core/editing/commands/document_exec_command.cc b/third_party/blink/renderer/core/editing/commands/document_exec_command.cc
index 9cbe75b..fcae634b 100644
--- a/third_party/blink/renderer/core/editing/commands/document_exec_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/document_exec_command.cc
@@ -35,6 +35,7 @@
 #include "third_party/blink/renderer/core/editing/commands/editor_command.h"
 #include "third_party/blink/renderer/core/editing/editing_tri_state.h"
 #include "third_party/blink/renderer/core/editing/editor.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/html/forms/text_control_element.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
diff --git a/third_party/blink/renderer/core/editing/commands/style_commands.cc b/third_party/blink/renderer/core/editing/commands/style_commands.cc
index 9063088..2c278620 100644
--- a/third_party/blink/renderer/core/editing/commands/style_commands.cc
+++ b/third_party/blink/renderer/core/editing/commands/style_commands.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/editing/visible_position.h"
 #include "third_party/blink/renderer/core/editing/writing_direction.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/html/html_font_element.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/editing/commands/typing_command.cc b/third_party/blink/renderer/core/editing/commands/typing_command.cc
index e877e165..39d4fbb 100644
--- a/third_party/blink/renderer/core/editing/commands/typing_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/typing_command.cc
@@ -50,6 +50,7 @@
 #include "third_party/blink/renderer/core/editing/visible_units.h"
 #include "third_party/blink/renderer/core/events/before_text_inserted_event.h"
 #include "third_party/blink/renderer/core/events/text_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/html/html_br_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
diff --git a/third_party/blink/renderer/core/editing/commands/undo_step.cc b/third_party/blink/renderer/core/editing/commands/undo_step.cc
index 1a3613e..a848cdb5 100644
--- a/third_party/blink/renderer/core/editing/commands/undo_step.cc
+++ b/third_party/blink/renderer/core/editing/commands/undo_step.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/editing/editor.h"
 #include "third_party/blink/renderer/core/editing/selection_template.h"
 #include "third_party/blink/renderer/core/editing/set_selection_options.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/editing/granularity_strategy.cc b/third_party/blink/renderer/core/editing/granularity_strategy.cc
index c6e06db1..0acec86 100644
--- a/third_party/blink/renderer/core/editing/granularity_strategy.cc
+++ b/third_party/blink/renderer/core/editing/granularity_strategy.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/editing/visible_position.h"
 #include "third_party/blink/renderer/core/editing/visible_selection.h"
 #include "third_party/blink/renderer/core/editing/visible_units.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
index 91bacfe..24173c6 100644
--- a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
+++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -28,6 +28,7 @@
 
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
 #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
 #include "third_party/blink/renderer/core/dom/range.h"
 #include "third_party/blink/renderer/core/dom/text.h"
@@ -46,6 +47,7 @@
 #include "third_party/blink/renderer/core/editing/state_machines/backward_code_point_state_machine.h"
 #include "third_party/blink/renderer/core/editing/state_machines/forward_code_point_state_machine.h"
 #include "third_party/blink/renderer/core/events/composition_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/html/forms/html_input_element.h"
 #include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
diff --git a/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc b/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc
index 0de20f16..037cbee5 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc
+++ b/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc
@@ -17,6 +17,7 @@
 #include "third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h"
 #include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
 #include "third_party/blink/renderer/core/editing/visible_position.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/events/animation_event.cc b/third_party/blink/renderer/core/events/animation_event.cc
index caaf3a21..ff1f40a 100644
--- a/third_party/blink/renderer/core/events/animation_event.cc
+++ b/third_party/blink/renderer/core/events/animation_event.cc
@@ -25,6 +25,8 @@
 
 #include "third_party/blink/renderer/core/events/animation_event.h"
 
+#include "third_party/blink/renderer/core/event_names.h"
+
 namespace blink {
 
 AnimationEvent::AnimationEvent() : elapsed_time_(0.0) {}
diff --git a/third_party/blink/renderer/core/events/animation_playback_event.cc b/third_party/blink/renderer/core/events/animation_playback_event.cc
index bcfcc250..538e58d 100644
--- a/third_party/blink/renderer/core/events/animation_playback_event.cc
+++ b/third_party/blink/renderer/core/events/animation_playback_event.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/core/events/animation_playback_event.h"
 
+#include "third_party/blink/renderer/core/event_names.h"
+
 namespace blink {
 
 AnimationPlaybackEvent::AnimationPlaybackEvent(const AtomicString& type,
diff --git a/third_party/blink/renderer/core/events/application_cache_error_event.cc b/third_party/blink/renderer/core/events/application_cache_error_event.cc
index 0c78953e..4c64c2a4 100644
--- a/third_party/blink/renderer/core/events/application_cache_error_event.cc
+++ b/third_party/blink/renderer/core/events/application_cache_error_event.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/core/events/application_cache_error_event.h"
 
+#include "third_party/blink/renderer/core/event_type_names.h"
+
 namespace blink {
 
 static const String& ErrorReasonToString(
diff --git a/third_party/blink/renderer/core/events/application_cache_error_event.h b/third_party/blink/renderer/core/events/application_cache_error_event.h
index 0acf164..c293a8e 100644
--- a/third_party/blink/renderer/core/events/application_cache_error_event.h
+++ b/third_party/blink/renderer/core/events/application_cache_error_event.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/public/platform/web_application_cache_host_client.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_names.h"
 #include "third_party/blink/renderer/core/events/application_cache_error_event_init.h"
 #include "third_party/blink/renderer/core/loader/appcache/application_cache_host.h"
 
diff --git a/third_party/blink/renderer/core/events/before_text_inserted_event.cc b/third_party/blink/renderer/core/events/before_text_inserted_event.cc
index 460379e..c08be5d 100644
--- a/third_party/blink/renderer/core/events/before_text_inserted_event.cc
+++ b/third_party/blink/renderer/core/events/before_text_inserted_event.cc
@@ -25,6 +25,9 @@
 
 #include "third_party/blink/renderer/core/events/before_text_inserted_event.h"
 
+#include "third_party/blink/renderer/core/event_names.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
+
 namespace blink {
 
 BeforeTextInsertedEvent::BeforeTextInsertedEvent(const String& text)
diff --git a/third_party/blink/renderer/core/events/before_unload_event.h b/third_party/blink/renderer/core/events/before_unload_event.h
index 76c99f8..f82a6a78 100644
--- a/third_party/blink/renderer/core/events/before_unload_event.h
+++ b/third_party/blink/renderer/core/events/before_unload_event.h
@@ -26,6 +26,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_BEFORE_UNLOAD_EVENT_H_
 
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_names.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/events/drag_event.cc b/third_party/blink/renderer/core/events/drag_event.cc
index 0b5579c7..6d592f6 100644
--- a/third_party/blink/renderer/core/events/drag_event.cc
+++ b/third_party/blink/renderer/core/events/drag_event.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/renderer/core/clipboard/data_transfer.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/events/focus_event.cc b/third_party/blink/renderer/core/events/focus_event.cc
index 536b99d..68cb3ae 100644
--- a/third_party/blink/renderer/core/events/focus_event.cc
+++ b/third_party/blink/renderer/core/events/focus_event.cc
@@ -27,6 +27,7 @@
 
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/events/keyboard_event.cc b/third_party/blink/renderer/core/events/keyboard_event.cc
index 7f8822b..16e99ca 100644
--- a/third_party/blink/renderer/core/events/keyboard_event.cc
+++ b/third_party/blink/renderer/core/events/keyboard_event.cc
@@ -26,6 +26,8 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_input_event.h"
 #include "third_party/blink/renderer/core/editing/ime/input_method_controller.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/input/input_device_capabilities.h"
 #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
diff --git a/third_party/blink/renderer/core/events/mouse_event.cc b/third_party/blink/renderer/core/events/mouse_event.cc
index 47c4dc9b..8feab62b 100644
--- a/third_party/blink/renderer/core/events/mouse_event.cc
+++ b/third_party/blink/renderer/core/events/mouse_event.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/public/platform/web_pointer_properties.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
diff --git a/third_party/blink/renderer/core/events/mouse_event.h b/third_party/blink/renderer/core/events/mouse_event.h
index 41182b0c..01753e4 100644
--- a/third_party/blink/renderer/core/events/mouse_event.h
+++ b/third_party/blink/renderer/core/events/mouse_event.h
@@ -26,8 +26,11 @@
 
 #include "third_party/blink/public/platform/web_menu_source_type.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h"
 #include "third_party/blink/renderer/core/events/mouse_event_init.h"
 #include "third_party/blink/renderer/core/events/ui_event_with_key_state.h"
+#include "third_party/blink/renderer/platform/geometry/double_point.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 
 namespace blink {
 class DataTransfer;
diff --git a/third_party/blink/renderer/core/events/page_transition_event.cc b/third_party/blink/renderer/core/events/page_transition_event.cc
index 79fbfc2..aa69128 100644
--- a/third_party/blink/renderer/core/events/page_transition_event.cc
+++ b/third_party/blink/renderer/core/events/page_transition_event.cc
@@ -25,6 +25,8 @@
 
 #include "third_party/blink/renderer/core/events/page_transition_event.h"
 
+#include "third_party/blink/renderer/core/event_names.h"
+
 namespace blink {
 
 PageTransitionEvent::PageTransitionEvent() : persisted_(false) {}
diff --git a/third_party/blink/renderer/core/events/pointer_event.cc b/third_party/blink/renderer/core/events/pointer_event.cc
index 88fdc4f..116c06a 100644
--- a/third_party/blink/renderer/core/events/pointer_event.cc
+++ b/third_party/blink/renderer/core/events/pointer_event.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/events/pointer_event_factory.cc b/third_party/blink/renderer/core/events/pointer_event_factory.cc
index f3e6855..563fb7d3 100644
--- a/third_party/blink/renderer/core/events/pointer_event_factory.cc
+++ b/third_party/blink/renderer/core/events/pointer_event_factory.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/events/pointer_event_factory.h"
 
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/platform/geometry/float_size.h"
 
diff --git a/third_party/blink/renderer/core/events/pop_state_event.cc b/third_party/blink/renderer/core/events/pop_state_event.cc
index ceb416a..60806ea 100644
--- a/third_party/blink/renderer/core/events/pop_state_event.cc
+++ b/third_party/blink/renderer/core/events/pop_state_event.cc
@@ -27,6 +27,8 @@
 #include "third_party/blink/renderer/core/events/pop_state_event.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/core/event_names.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/core/frame/history.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/events/progress_event.cc b/third_party/blink/renderer/core/events/progress_event.cc
index 9e0b9b04..ea992bc 100644
--- a/third_party/blink/renderer/core/events/progress_event.cc
+++ b/third_party/blink/renderer/core/events/progress_event.cc
@@ -25,6 +25,8 @@
 
 #include "third_party/blink/renderer/core/events/progress_event.h"
 
+#include "third_party/blink/renderer/core/event_names.h"
+
 namespace blink {
 
 ProgressEvent::ProgressEvent()
diff --git a/third_party/blink/renderer/core/events/promise_rejection_event.cc b/third_party/blink/renderer/core/events/promise_rejection_event.cc
index 8857283..90fed2e 100644
--- a/third_party/blink/renderer/core/events/promise_rejection_event.cc
+++ b/third_party/blink/renderer/core/events/promise_rejection_event.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/events/promise_rejection_event.h"
 
+#include "third_party/blink/renderer/core/event_names.h"
 #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/events/resource_progress_event.cc b/third_party/blink/renderer/core/events/resource_progress_event.cc
index 21725ed..0913086 100644
--- a/third_party/blink/renderer/core/events/resource_progress_event.cc
+++ b/third_party/blink/renderer/core/events/resource_progress_event.cc
@@ -26,6 +26,8 @@
 
 #include "third_party/blink/renderer/core/events/resource_progress_event.h"
 
+#include "third_party/blink/renderer/core/event_names.h"
+
 namespace blink {
 
 ResourceProgressEvent::ResourceProgressEvent(const AtomicString& type,
diff --git a/third_party/blink/renderer/core/events/security_policy_violation_event.h b/third_party/blink/renderer/core/events/security_policy_violation_event.h
index 92313893..6b9f32d 100644
--- a/third_party/blink/renderer/core/events/security_policy_violation_event.h
+++ b/third_party/blink/renderer/core/events/security_policy_violation_event.h
@@ -27,6 +27,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_SECURITY_POLICY_VIOLATION_EVENT_H_
 
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_names.h"
 #include "third_party/blink/renderer/core/events/security_policy_violation_event_init.h"
 #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
 
diff --git a/third_party/blink/renderer/core/events/touch_event.cc b/third_party/blink/renderer/core/events/touch_event.cc
index 4cc304c..f9a4414 100644
--- a/third_party/blink/renderer/core/events/touch_event.cc
+++ b/third_party/blink/renderer/core/events/touch_event.cc
@@ -28,6 +28,7 @@
 
 #include "third_party/blink/public/platform/web_coalesced_input_event.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 #include "third_party/blink/renderer/core/frame/frame_console.h"
 #include "third_party/blink/renderer/core/frame/intervention.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
diff --git a/third_party/blink/renderer/core/events/touch_event_test.cc b/third_party/blink/renderer/core/events/touch_event_test.cc
index c7e9b86..652db73 100644
--- a/third_party/blink/renderer/core/events/touch_event_test.cc
+++ b/third_party/blink/renderer/core/events/touch_event_test.cc
@@ -8,6 +8,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/frame/frame_console.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/loader/empty_clients.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
diff --git a/third_party/blink/renderer/core/events/transition_event.cc b/third_party/blink/renderer/core/events/transition_event.cc
index 47dd89d..a8fedb14 100644
--- a/third_party/blink/renderer/core/events/transition_event.cc
+++ b/third_party/blink/renderer/core/events/transition_event.cc
@@ -26,6 +26,8 @@
 
 #include "third_party/blink/renderer/core/events/transition_event.h"
 
+#include "third_party/blink/renderer/core/event_names.h"
+
 namespace blink {
 
 TransitionEvent::TransitionEvent() : elapsed_time_(0) {}
diff --git a/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc b/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc
index 6e92087..38aa8e7 100644
--- a/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc
+++ b/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/core/events/visual_viewport_resize_event.h"
 
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc b/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc
index 51832e8..0eeac68 100644
--- a/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc
+++ b/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/core/events/visual_viewport_scroll_event.h"
 
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/events/wheel_event.cc b/third_party/blink/renderer/core/events/wheel_event.cc
index 7ab79e5a..c8c64c6 100644
--- a/third_party/blink/renderer/core/events/wheel_event.cc
+++ b/third_party/blink/renderer/core/events/wheel_event.cc
@@ -24,6 +24,8 @@
 #include "third_party/blink/renderer/core/events/wheel_event.h"
 
 #include "third_party/blink/renderer/core/clipboard/data_transfer.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 
 namespace blink {
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 e9e57f6..08bc3a23 100644
--- a/third_party/blink/renderer/core/exported/web_frame_serializer.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_serializer.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
 #include "third_party/blink/renderer/core/frame/frame.h"
 #include "third_party/blink/renderer/core/frame/frame_serializer.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/remote_frame.h"
 #include "third_party/blink/renderer/core/frame/web_frame_serializer_impl.h"
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc
index c828a08..b973276 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -108,6 +108,7 @@
 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
 #include "third_party/blink/renderer/core/frame/find_in_page.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/remote_frame.h"
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index 2cd062e..a60244e 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -44,6 +44,7 @@
 #include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
 #include "third_party/blink/renderer/core/exported/web_settings_impl.h"
 #include "third_party/blink/renderer/core/exported/web_view_impl.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
index b2add6c..d1876f4 100644
--- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/core/execution_context/security_context.h"
 #include "third_party/blink/renderer/core/exported/web_view_impl.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/remote_frame_client_impl.h"
 #include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 23f0d6f..59953653 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -95,6 +95,7 @@
 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
 #include "third_party/blink/renderer/core/frame/fullscreen_controller.h"
 #include "third_party/blink/renderer/core/frame/link_highlights.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc
index 846ecd45..e008a6be 100644
--- a/third_party/blink/renderer/core/exported/web_view_test.cc
+++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -87,6 +87,7 @@
 #include "third_party/blink/renderer/core/exported/web_view_impl.h"
 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
diff --git a/third_party/blink/renderer/core/frame/mhtml_loading_test.cc b/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
index 7601d88..cba070e9 100644
--- a/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
+++ b/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/location.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.h b/third_party/blink/renderer/core/frame/visual_viewport.h
index ab07c17..4ebd13c 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport.h
+++ b/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -48,13 +48,14 @@
 
 namespace blink {
 
+class EffectPaintPropertyNode;
 class GraphicsContext;
 class GraphicsLayer;
 class IntRect;
 class IntSize;
 class LocalFrame;
 class Page;
-class EffectPaintPropertyNode;
+class RootFrameViewport;
 class ScrollPaintPropertyNode;
 class TransformPaintPropertyNode;
 struct PaintPropertyTreeBuilderFragmentContext;
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
index 0d62b887..710b136e 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc
+++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/browser_controls.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc
index e70567c..6590731 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -46,6 +46,7 @@
 #include "third_party/blink/renderer/core/events/gesture_event.h"
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
 #include "third_party/blink/renderer/core/events/mouse_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/html/forms/form_controller.h"
diff --git a/third_party/blink/renderer/core/html/html_dialog_element.cc b/third_party/blink/renderer/core/html/html_dialog_element.cc
index 9e3b438..e3143d8 100644
--- a/third_party/blink/renderer/core/html/html_dialog_element.cc
+++ b/third_party/blink/renderer/core/html/html_dialog_element.cc
@@ -28,6 +28,7 @@
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc
index fc1a42b..bd962a0 100644
--- a/third_party/blink/renderer/core/html/html_element.cc
+++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/html/forms/html_form_element.h"
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
index 4b94aea2..2d8afad7 100644
--- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc
+++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
diff --git a/third_party/blink/renderer/core/html/image_document_test.cc b/third_party/blink/renderer/core/html/image_document_test.cc
index 05cf416..4a293f7 100644
--- a/third_party/blink/renderer/core/html/image_document_test.cc
+++ b/third_party/blink/renderer/core/html/image_document_test.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/document_parser.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/geometry/dom_rect.h"
diff --git a/third_party/blink/renderer/core/input/gesture_manager.cc b/third_party/blink/renderer/core/input/gesture_manager.cc
index 7f90e404..6f7d66c4 100644
--- a/third_party/blink/renderer/core/input/gesture_manager.cc
+++ b/third_party/blink/renderer/core/input/gesture_manager.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
 #include "third_party/blink/renderer/core/editing/selection_controller.h"
 #include "third_party/blink/renderer/core/events/gesture_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
diff --git a/third_party/blink/renderer/core/input/keyboard_event_manager.cc b/third_party/blink/renderer/core/input/keyboard_event_manager.cc
index a3be8df0..4d9cb5a 100644
--- a/third_party/blink/renderer/core/input/keyboard_event_manager.cc
+++ b/third_party/blink/renderer/core/input/keyboard_event_manager.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
 #include "third_party/blink/renderer/core/editing/editor.h"
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/html/html_dialog_element.h"
 #include "third_party/blink/renderer/core/input/event_handler.h"
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc
index 862480d..db5b1bfc 100644
--- a/third_party/blink/renderer/core/input/mouse_event_manager.cc
+++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/core/events/drag_event.h"
 #include "third_party/blink/renderer/core/events/mouse_event.h"
 #include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
diff --git a/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc b/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc
index 5525e3d..3b3c968 100644
--- a/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc
+++ b/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/public/platform/web_mouse_wheel_event.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/events/wheel_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/input/event_handler.h"
 #include "third_party/blink/renderer/core/input/event_handling_util.h"
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc
index 8283468..9edf150 100644
--- a/third_party/blink/renderer/core/input/pointer_event_manager.cc
+++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -7,6 +7,7 @@
 #include "base/auto_reset.h"
 #include "third_party/blink/public/platform/web_touch_event.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
 #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
 #include "third_party/blink/renderer/core/events/mouse_event.h"
diff --git a/third_party/blink/renderer/core/input/scroll_manager.cc b/third_party/blink/renderer/core/input/scroll_manager.cc
index 76198bea..42d6a75 100644
--- a/third_party/blink/renderer/core/input/scroll_manager.cc
+++ b/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/events/gesture_event.h"
 #include "third_party/blink/renderer/core/frame/browser_controls.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
 #include "third_party/blink/renderer/core/input/event_handler.h"
diff --git a/third_party/blink/renderer/core/input/scroll_snap_test.cc b/third_party/blink/renderer/core/input/scroll_snap_test.cc
index e0b7f9c..ab29a7e 100644
--- a/third_party/blink/renderer/core/input/scroll_snap_test.cc
+++ b/third_party/blink/renderer/core/input/scroll_snap_test.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/input/event_handler.h"
 #include "third_party/blink/renderer/core/input/scroll_manager.h"
 #include "third_party/blink/renderer/core/layout/layout_box.h"
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.cc b/third_party/blink/renderer/core/input/touch_event_manager.cc
index 6f2fa50..7448ec4 100644
--- a/third_party/blink/renderer/core/input/touch_event_manager.cc
+++ b/third_party/blink/renderer/core/input/touch_event_manager.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/events/touch_event.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
 #include "third_party/blink/renderer/core/input/event_handling_util.h"
diff --git a/third_party/blink/renderer/core/inspector/thread_debugger.cc b/third_party/blink/renderer/core/inspector/thread_debugger.cc
index c44a833..a8256bca 100644
--- a/third_party/blink/renderer/core/inspector/thread_debugger.cc
+++ b/third_party/blink/renderer/core/inspector/thread_debugger.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_node_list.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
 #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.h"
 #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 9251606..282e548 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/public/platform/web_scroll_into_view_params.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
diff --git a/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc b/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc
index f81321a..17e7e45 100644
--- a/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc
+++ b/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h"
 
+#include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/core/mojo/mojo_handle.h"
 #include "third_party/blink/renderer/core/mojo/test/mojo_interface_request_event_init.h"
 
diff --git a/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h b/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h
index 33d9f34..d050825 100644
--- a/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h
+++ b/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_MOJO_TEST_MOJO_INTERFACE_REQUEST_EVENT_H_
 
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_names.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc
index b2c5d8f..d81228d 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -62,6 +62,7 @@
 #include "third_party/blink/renderer/core/exported/web_settings_impl.h"
 #include "third_party/blink/renderer/core/exported/web_view_impl.h"
 #include "third_party/blink/renderer/core/frame/browser_controls.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
diff --git a/third_party/blink/renderer/core/page/drag_controller.cc b/third_party/blink/renderer/core/page/drag_controller.cc
index 208bc07a..a1d141f 100644
--- a/third_party/blink/renderer/core/page/drag_controller.cc
+++ b/third_party/blink/renderer/core/page/drag_controller.cc
@@ -55,6 +55,7 @@
 #include "third_party/blink/renderer/core/editing/selection_template.h"
 #include "third_party/blink/renderer/core/editing/serializers/serialization.h"
 #include "third_party/blink/renderer/core/events/text_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index d49490d..05e8277 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
 #include "third_party/blink/renderer/core/frame/frame_console.h"
 #include "third_party/blink/renderer/core/frame/link_highlights.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/page_scale_constraints.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
index d39a89c3..0b7f57b 100644
--- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/renderer/core/frame/browser_controls.h"
 #include "third_party/blink/renderer/core/frame/dom_visual_viewport.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc b/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
index 2306f95..4da47eb4 100644
--- a/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/public/web/web_script_source.h"
 #include "third_party/blink/renderer/bindings/core/v8/scroll_into_view_options_or_boolean.h"
 #include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/scroll_into_view_options.h"
 #include "third_party/blink/renderer/core/frame/scroll_to_options.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
index 9e3f6f2..a0028bd 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
index 1e48ae9..e4ec06d 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/core/css/style_sheet_list.h"
 #include "third_party/blink/renderer/core/exported/web_view_impl.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
diff --git a/third_party/blink/renderer/core/timing/event_timing.cc b/third_party/blink/renderer/core/timing/event_timing.cc
index d1ad5e97..acef9dfb 100644
--- a/third_party/blink/renderer/core/timing/event_timing.cc
+++ b/third_party/blink/renderer/core/timing/event_timing.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/events/pointer_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/timing/dom_window_performance.h"
 #include "third_party/blink/renderer/core/timing/performance_event_timing.h"
 #include "third_party/blink/renderer/platform/wtf/time.h"
diff --git a/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc b/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
index db1cdf8..818b31e 100644
--- a/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
+++ b/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
@@ -9,7 +9,7 @@
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/event_type_names.h"
-#include "third_party/blink/renderer/core/frame/dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
diff --git a/third_party/blink/renderer/modules/geolocation/geoposition.h b/third_party/blink/renderer/modules/geolocation/geoposition.h
index b985d3d..cbb5c44e 100644
--- a/third_party/blink/renderer/modules/geolocation/geoposition.h
+++ b/third_party/blink/renderer/modules/geolocation/geoposition.h
@@ -26,6 +26,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOPOSITION_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOPOSITION_H_
 
+#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/platform/bindings/script_wrappable.h"
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc
index 4ce754d0..2d0b147 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/core/events/mouse_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/html/html_html_element.h"
 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
index 293c523f..456171e 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
 #include "third_party/blink/renderer/core/events/pointer_event.h"
 #include "third_party/blink/renderer/core/events/touch_event.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/html/html_div_element.h"
 #include "third_party/blink/renderer/core/html/html_style_element.h"
 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_request.cc b/third_party/blink/renderer/modules/mediastream/user_media_request.cc
index 89c594c6..7154d9f 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_request.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_request.cc
@@ -550,14 +550,12 @@
   MediaStreamTrackVector audio_tracks = stream->getAudioTracks();
   for (MediaStreamTrackVector::iterator iter = audio_tracks.begin();
        iter != audio_tracks.end(); ++iter) {
-    (*iter)->Component()->Source()->SetConstraints(audio_);
     (*iter)->SetConstraints(audio_);
   }
 
   MediaStreamTrackVector video_tracks = stream->getVideoTracks();
   for (MediaStreamTrackVector::iterator iter = video_tracks.begin();
        iter != video_tracks.end(); ++iter) {
-    (*iter)->Component()->Source()->SetConstraints(video_);
     (*iter)->SetConstraints(video_);
   }
 
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc
index d057a3a5..c1bbca3 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -25,6 +25,8 @@
 #include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
 #include "third_party/blink/renderer/core/frame/frame_owner.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
index d20987f..edb5571 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
@@ -25,6 +25,8 @@
 
 #include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h"
 
+#include "third_party/blink/renderer/core/event_type_names.h"
+
 namespace blink {
 
 RTCDTMFToneChangeEvent* RTCDTMFToneChangeEvent::Create(const String& tone) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
index 377dae9..97ee5a3 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
@@ -24,6 +24,7 @@
 
 #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h"
 
+#include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.h"
 
diff --git a/third_party/blink/renderer/modules/sensor/sensor.cc b/third_party/blink/renderer/modules/sensor/sensor.cc
index a3ea53a..484baee 100644
--- a/third_party/blink/renderer/modules/sensor/sensor.cc
+++ b/third_party/blink/renderer/modules/sensor/sensor.cc
@@ -8,6 +8,7 @@
 #include "services/device/public/mojom/sensor.mojom-blink.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/timing/dom_window_performance.h"
 #include "third_party/blink/renderer/core/timing/window_performance.h"
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_error.cc b/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
index 44f1bd8..1e2ba225 100644
--- a/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
+++ b/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
@@ -24,6 +24,8 @@
  */
 
 #include "third_party/blink/renderer/modules/speech/speech_recognition_error.h"
+
+#include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_event.cc b/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
index c6a3e2f..8c77fcd 100644
--- a/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
+++ b/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
@@ -25,6 +25,8 @@
 
 #include "third_party/blink/renderer/modules/speech/speech_recognition_event.h"
 
+#include "third_party/blink/renderer/core/event_type_names.h"
+
 namespace blink {
 
 SpeechRecognitionEvent* SpeechRecognitionEvent::Create(
diff --git a/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc b/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc
index b7c5349..5565fbf 100644
--- a/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc
+++ b/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/dom_implementation.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
diff --git a/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc b/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc
index 3c3dbed..b580ddff 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc
@@ -24,6 +24,8 @@
  */
 
 #include "third_party/blink/renderer/modules/webaudio/audio_processing_event.h"
+
+#include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/modules/webaudio/audio_processing_event_init.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc
index 8156266..29ae5094 100644
--- a/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc
+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc
@@ -25,6 +25,8 @@
 
 #include "third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h"
 
+#include "third_party/blink/renderer/core/event_type_names.h"
+
 namespace blink {
 
 OfflineAudioCompletionEvent* OfflineAudioCompletionEvent::Create() {
diff --git a/third_party/blink/renderer/modules/webmidi/midi_message_event.h b/third_party/blink/renderer/modules/webmidi/midi_message_event.h
index 68247d1..5a2336d1 100644
--- a/third_party/blink/renderer/modules/webmidi/midi_message_event.h
+++ b/third_party/blink/renderer/modules/webmidi/midi_message_event.h
@@ -32,6 +32,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_MESSAGE_EVENT_H_
 
 #include "base/time/time.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
 #include "third_party/blink/renderer/modules/event_modules.h"
 
diff --git a/third_party/blink/renderer/modules/webusb/usb.cc b/third_party/blink/renderer/modules/webusb/usb.cc
index 471f0e64..83abdef 100644
--- a/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/third_party/blink/renderer/modules/webusb/usb.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/frame/frame.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/modules/event_target_modules.h"
 #include "third_party/blink/renderer/modules/webusb/usb_connection_event.h"
 #include "third_party/blink/renderer/modules/webusb/usb_device.h"
diff --git a/third_party/blink/renderer/platform/exported/web_media_stream_source.cc b/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
index f0569624..3af4b48 100644
--- a/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
+++ b/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
@@ -177,11 +177,6 @@
       auto_gain_control, noise_supression);
 }
 
-WebMediaConstraints WebMediaStreamSource::Constraints() {
-  DCHECK(!private_.IsNull());
-  return private_->Constraints();
-}
-
 void WebMediaStreamSource::SetCapabilities(
     const WebMediaStreamSource::Capabilities& capabilities) {
   DCHECK(!private_.IsNull());
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_source.h b/third_party/blink/renderer/platform/mediastream/media_stream_source.h
index dfc765b..2c13854 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_source.h
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_source.h
@@ -103,10 +103,6 @@
                                     bool auto_gain_control,
                                     bool noise_supression);
 
-  void SetConstraints(WebMediaConstraints constraints) {
-    constraints_ = constraints;
-  }
-  WebMediaConstraints Constraints() { return constraints_; }
   void GetSettings(WebMediaStreamTrack::Settings&);
 
   const WebMediaStreamSource::Capabilities& GetCapabilities() {
diff --git a/third_party/espresso/BUILD.gn b/third_party/espresso/BUILD.gn
index 3986e49..5652ef6 100644
--- a/third_party/espresso/BUILD.gn
+++ b/third_party/espresso/BUILD.gn
@@ -29,10 +29,10 @@
   testonly = true
   jar_path = "lib/espresso-core-release-no-dep.jar"
   deps = [
+    "//third_party/android_deps:javax_inject_javax_inject_java",
     "//third_party/android_tools:android_support_annotations_java",
     "//third_party/guava:guava_android_java",
     "//third_party/hamcrest:hamcrest_core_java",
-    "//third_party/javax_inject:javax_inject_java",
   ]
 }
 
diff --git a/third_party/javax_inject/BUILD.gn b/third_party/javax_inject/BUILD.gn
deleted file mode 100644
index e9e3aec..0000000
--- a/third_party/javax_inject/BUILD.gn
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/rules.gni")
-
-android_java_prebuilt("javax_inject_java") {
-  jar_path = "lib/javax.inject.jar"
-}
diff --git a/third_party/javax_inject/OWNERS b/third_party/javax_inject/OWNERS
deleted file mode 100644
index 2cfd26c3..0000000
--- a/third_party/javax_inject/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-jbudorick@chromium.org
-mikecase@chromium.org
-yolandyan@chromium.org
diff --git a/third_party/javax_inject/README.chromium b/third_party/javax_inject/README.chromium
deleted file mode 100644
index 65867af..0000000
--- a/third_party/javax_inject/README.chromium
+++ /dev/null
@@ -1,19 +0,0 @@
-Name: javax.inject
-Short Name: javax_inject
-URL: http://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html
-Version: 1
-License: Apache 2.0
-License File: NOT_SHIPPED
-Security Critical: no
-License Android Compatible: yes
-
-Description:
-This package specifies a means for obtaining objects in such a way as to
-maximize reusability, testability and maintainability compared to traditional
-approaches such as constructors, factories, and service locators (e.g., JNDI).
-This process, known as dependency injection, is beneficial to most nontrivial
-applications.
-IMPORTANT: There should only be one version of espresso library
-(crbug.com/622057)
-
-Local Modifications: None
diff --git a/third_party/javax_inject/cipd.yaml b/third_party/javax_inject/cipd.yaml
deleted file mode 100644
index c3e5a875..0000000
--- a/third_party/javax_inject/cipd.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# To create CIPD package run the following command.
-# cipd create --pkg-def cipd.yaml -tag version:$(cat version.txt)
-package: chromium/third_party/javax_inject
-description: javax_inject Java library
-data:
-  - file: lib/javax.inject.jar
diff --git a/tools/android/roll/android_deps/build.gradle b/tools/android/roll/android_deps/build.gradle
index edecdb2..c9f422f 100644
--- a/tools/android/roll/android_deps/build.gradle
+++ b/tools/android/roll/android_deps/build.gradle
@@ -63,6 +63,16 @@
     compile "com.android.support:design:${supportLibVersion}"
 
     compile "com.android.support:multidex:1.0.0"
+
+    // Dagger
+    def daggerVersion = '2.17'
+    compile "com.google.dagger:dagger:${daggerVersion}"
+    compile "com.google.dagger:dagger-android:${daggerVersion}"
+    compile "com.google.dagger:dagger-android-support:${daggerVersion}"
+    compile "javax.inject:javax.inject:1"
+
+    annotationProcessor "com.google.dagger:dagger-compiler:${daggerVersion}"
+    annotationProcessor "com.google.dagger:dagger-android-processor:${daggerVersion}"
 }
 
 task setUpRepository(type: BuildConfigGenerator) {
diff --git a/tools/android/roll/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy b/tools/android/roll/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
index 22784c59..f1df4c088 100644
--- a/tools/android/roll/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
+++ b/tools/android/roll/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
@@ -20,6 +20,26 @@
 class ChromiumDepGraph {
     final def dependencies = new HashMap<String, DependencyDescription>()
 
+    // Some libraries don't properly fill their POM with the appropriate licensing information.
+    // It is provided here from manual lookups.
+    final def FALLBACK_PROPERTIES = [
+        'com_google_googlejavaformat_google_java_format': new DependencyDescription(
+          url: "https://github.com/google/google-java-format",
+          licenseUrl: "https://www.apache.org/licenses/LICENSE-2.0.txt",
+          licenseName: "Apache 2.0"),
+        'com_google_guava_guava': new DependencyDescription(
+          url: "https://github.com/google/guava",
+          licenseUrl: "https://www.apache.org/licenses/LICENSE-2.0.txt",
+          licenseName: "Apache 2.0"),
+        'org_codehaus_mojo_animal_sniffer_annotations': new DependencyDescription(
+          url: "http://www.mojohaus.org/animal-sniffer/animal-sniffer-annotations/",
+          licenseUrl: "https://opensource.org/licenses/mit-license.php",
+          licenseName: "MIT"),
+        'org_checkerframework_checker_compat_qual' :new DependencyDescription(
+          licenseUrl: "https://github.com/typetools/checker-framework/blob/master/LICENSE.txt",
+          licenseName: "GPL v2 (with the classpath exception)"),
+    ]
+
     Project project
 
     void collectDependencies() {
@@ -143,6 +163,13 @@
             if (dep.id?.endsWith("_license")) {
                 dep.exclude = true
             }
+        } else if (dep.licenseName?.isEmpty()) {
+            def fallbackProperties = FALLBACK_PROPERTIES.get(id)
+            if (fallbackProperties != null) {
+                project.logger.debug("Using fallback properties for ${id}")
+                dep.licenseName = fallbackProperties.licenseName
+                dep.licenseUrl = fallbackProperties.licenseUrl
+            }
         }
 
         return dep